pax_global_header00006660000000000000000000000064114540121620014506gustar00rootroot0000000000000052 comment=8d51d9477995f852d4dd50ee8797826cf78c2fa7 AUTHORS000066400000000000000000000006361145401216200121270ustar00rootroot00000000000000Gnucap is primarily the work of Albert Davis. Here is a list of some of the contributors who have contributed more than a bug report: Dan McMahill - "autoconf" interface, NetBSD package Stuart Brorson - configuration mods Hamish Moffatt - Debian package Telford Tendys - documentation and convergence Dmitry Nadezhin - "electric" interface Simon Hoffe - Command line editing and history COPYING000066400000000000000000001045131145401216200121110ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ChangeLog000066400000000000000000001122501145401216200126250ustar00rootroot00000000000000Gnucap revision history ------------------------------------------------------------------ ------------------------------------------------------------------ Gnucap 0.34 release notes (02/01/2004) This is a bug fix and compatibility release. 1. Fix bug causing incorrect interpolation of backwards tables. 2. Fix tanh overflow bug. 3. Fix some parsing bugs. 4. Fix occasional "double load" bug. 5. Fix AC sweep with one point. 6. Transient start time really works. 7. Fix occasional assert fail after option short is changed. 8. Fix memory leak resulting from failure to delete unused common. 9. Fix a Z probe bug that sometimes gave wrong answers. 10. Fix a limiting bug that sometimes caused non-convergence. 11. Configure handles isnan. 12. Improvements to logic initialization. It is still not correct. ------------------------------------------------------------------ Gnucap 0.33 release notes (01/12/2003) This is a bug fix and compatibility release. 0.32 was not widely distributed due to password problems and a heavy work load, so the release notes are repeated after the current ones. New features: 1. Add inductance probes, like capacitor. Bug fixes: 1. Fix xprobe duplicate default arg bug - shows in g++3.2. 2. Fix bug that sometimes caused a crash when changing a model after analysis. 3. Fix bug that caused an assert to fail (debug build) after removing a probe from an element. 4. Fix a dumb typo hack bug ddHAS_READLINE. Now history and command line editing really works. It was working, but somehow the hack slipped into the release code. ------------------------------------------------------------------ Gnucap 0.32 release notes (09/30/2002) New features: 1. Series resistance in the diode. It took 5 minutes to do, so it is embarrasing that it wasn't done before. 2. History and command line editing, using Gnu Readline. Thanks to Simon Hoffe for sending me the patch. 3. More parameters in the BJT model. This gives it better compatibility with commercial simulators. These parameters are beyond Spice 3f5. 4. "M" parameter in diode, BJT and MOS devices. M is the number of parallel devices. Some commercial simulators have this. Changes that may or may not be improvements. 1. The definition of the transient option "UIC" has changed. It is now Spice compatible, which means to not attempt to do any solution or consistency check. Just apply the values, assuming anything that isn't specified is 0. The old behavior was to attempt a solution while holding the IC values. Bug fixes: 1. voltage sync bug. It still doesn't fix the MOS 2 convergence problem. 2. Fix memory leak in POLY components. 3. Fix bug in Fourier that sometimes causes overrun (crash) and time sync errors. 4. Modelgen: fix bug in list parsing. 5. Some changes to eliminate warnings when compiling with g++ 3.1. 6. Use Euler differentiation on first step, because trap used a value that cannot be known then. Usually, this doesn't make much difference, but there are a few cases where the error can get magnified and trigger trapezoidal ringing, leading to a totally bogus result. It most cases, you could hide it with small enough steps. These cases should work with default settings now. 7. Fix bug that sometimes caused incorrect handling of initial conditions (UIC), 8. Fix bug that caused continuing a transient analysis to give incorrect results. Significant internal changes: 1. The inductor uses all of the same support functions as the capacitor, including "integrate", which is now correctly called "differentiate". 2. Most of the code is in place for named nodes. It mostly works and can be turned on with the option "namednodes". It is off by default because it is not complete. Most likely, it will be finished in the next release. Some things that are still partially implemented: 1. BSIM models, charge effects, "alpha0" parameter. (computed then ignored) 2. Configure still doesn't handle everything. 3. The model compiler still requires too much raw coding. 4. Named nodes. If you set the option "namednodes", it will support named nodes, but some things don't work, so it is off by default. 5. The preliminary IBIS code is now included. For now, it is a standalone executable, that reads an IBIS file and generates a netlist. The netlist requires some editing to use, and is not fully compatible anyway. It is included in hopes of recruiting help in finishing the project. Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. 2. An occasional bogus calculation in MOSFETS occurs when a device is reversed. This sometimes causes nonconvergence. 3. The "modify" command with multiple arguments seems to take only the first one. It used to work, but is broken in this release. I am not sure when it broke. ------------------------------------------------------------------ Gnucap 0.31 release notes (03/25/2002) The most significant changes are the BJT model and "binning". New features: 1. BJT model. 2. "Binning" for all MOS models. 3. Internal element: non-quasi-static poly-capacitor. (needed by BJT). 4. Enhancements to the data structures and model compiler to support binning in general. 5. A line prefixed by "*>" is not ignored, in spite of the fact that "*" usually begins a comment. This is a deliberate incompatibility with Spice. If you prefix a line by "*>" it will be interpreted as a non-comment in Gnucap, but a comment in Spice. 6. Circuit line prefixes of ">" and command prefixes of "-->" are ignored. This is so you can copy and paste whole lines, without having to manually remove the prompt string. Changes that may or may not be improvements. 1. It is not the default to include stray resistance in device models. The option "norstray" will revert to the old behavior. This is only a change to the default value of "rstray". Significant internal changes: 1. The internal element non-quasi-static poly-capacitor actually works. It is used by the BJT model, and will eventually be used by MOSFET models. 2. There are now two poly_g devices: "CPOLY_G" and "FPOLY_G". There are interface differences that impact modeling. Previously, there was only one, which is equivalent to the "FPOLY_G". Some things that are still partially implemented: 1. BSIM models, charge effects, "alpha0" parameter. (computed then ignored) 2. Configure still doesn't handle everything. 3. The model compiler still requires too much raw coding. General comments: The new BJT model seems to pass the CircuitSim90 test cases as well as anything else, except where a missing feature prevented it from working. A few files would not run because of named nodes. One file (ring11) failed completely. This file also has MOSFETs, with level 2 models. The MOS level 2 model is not as robust as the BJT. I believe the problem is due to the voltage sync bug that still impacts the MOS model. Most of the models have has a reasonable amount of testing in DC, but inadequate testing in AC and transient. The BJT model has had more testing than the others in AC and transient. All differences (relative to other simulators) that were observed can be attributed to differences in transient step size control or tolerance checking. Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. ------------------------------------------------------------------ GNUCAP 0.30 release notes (10/29/2001) The primary effort has been to finish the model compiler, to the point where it can handle most modeling issues. The second change is to re-release as "gnucap", and add some configuration features to be more consistent with other GNU software. New features: 1. More complete model compiler. 2. "./configure" makes compiling more like other GNU software. Some things that are still partially implemented: 1. Internal element: non-quasi-static poly-capacitor. 2. BSIM models, charge effects, "alpha0" parameter. (computed then ignored) 3. Configure still doesn't handle everything. 4. The model compiler still requires too much raw coding. Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. ------------------------------------------------------------------ ACS 0.29 release notes (06/30/2001) The primary effort has been to implement IBIS, which is still not done. The changes here are mostly infrastructure changes needed to support IBIS. New features: 1. "Fit" function has choice of fit order and extrapolation. You can have order 0, 1, 2, or 3. 2. "Posy" has even and odd options, to determine what happens in the negative region. 3. Modelgen improvements. It now is useful for the whole device, sometimes. It now handles probes and the device side of the model. The diode uses it completely. There are still a few missing features needed for the MOSFET and BJT. 4. Spice-3 compatible semiconductor resistor and capacitor. 5. "Table" model statement. Improvements, bug fixes, etc. 1. Option "numdgt" really works. 2. Better error messages from modelgen. 3. Code changes for optimization of commons. This should reduce memory use, sometimes, by sharing commons. Common sharing is still not fully implemented. 4. Fix two bugs that sometimes caused problems after a "modify" or on a "fault". 5. Better handling of "vmin" and "vmax". It should be much less likely that limiting causes convergence to a nonsense result. Some things that are still partially implemented: 1. Internal element: non-quasi-static poly-capacitor. 2. BSIM models, charge effects, "alpha0" parameter. (computed then ignored) Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. 2. The makefile does not set up the proper link for the model compiler. You need to do it manually. 3. On some systems, you will get a warning from the linker that "the use of 'tmpnam' is dangerous". You can ignore this warning. ------------------------------------------------------------------ ACS 0.28 release notes (09/05/2000) New features: 1. New probes: diode G, mos IBD, IBS, GBD, GBS. 2. New options: "floor" and "vfloor". (Floor was in the manual, but not in the simulator.) Improvements, bug fixes, etc. 1. There is a change to the way behavioral modeling conditionals are handled. It should now be 100% compatible with SPICE, considering the subset that duplicates SPICE. There are still significant extensions beyond SPICE, particularly that you can have behavioral resistors, capacitors, inductors, etc. 2. Parameter default calculations are now done in a manner consistent with Spice 3f5. Previously, it was supposedly consistent with Spice 2g6. 3. A bug in calculation of threshold voltage of the level 6 model, for P channel devices, has been fixed. 4. A bug in calculation of Meyer capacitances when the device is reversed has been fixed. This bug sometimes caused a discontinuity at vds=0. 5. I have added some smoothing to the Meyer mos capacitor models. This improves convergence. The down side is that sometimes the answers are different. It is probably a little better, when considering closeness to reality, but it is still Meyer's model. 6. MOSFET parasitic diodes are now the same as those used in Spice. 7. There are subtle changes in the diode model. I think this usually improves convergence. 8. Charge calculation in Meyer capacitors and diode capacitiors is now supposedly Spice 3 compatible. 9. An error in BSIM3 scaling has been fixed. Some things that are still partially implemented: 1. Internal element: non-quasi-static poly-capacitor. 2. BSIM models, charge effects. Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. 2. The makefile does not set up the proper link for the model compiler. You need to do it manually. 3. A bad setting of "vmax" and "vmin" can lead to convergence to a nonsense result. It is not as bad now as it used to be. ------------------------------------------------------------------ ACS 0.27 release notes (06/03/2000) New features: 1. BSIM3 model, DC. They work for AC and transient analysis, but only the DC effects actually work. The next release should have the charge effects. For now, it fakes it with Meyer's model. 2. A first cut at a model compiler, to aid in development of new models. Models are described in a ".model" file, which is processed to automatically generate the ".h" and ".cc" files. This version fully handles the ".model" statement part of it, but leaves the device and common sections the old way. Eventually, the entire process will be automated. The old way still works. 3. "Fit" behavioral modeling function, which fits a curve to a set of data. You can specify the order of the fit, which is piecewise polynomials. For now, the order may be 1 (linear, like PWL) or 3 (cubic splines). You may also specify the boundary consitions. 4. More probes. Some things that are partially implemented: 1. Internal element: non-quasi-static poly-capacitor. It is needed by the BSIM3 and EKV models. Eventually, it will be available as a netlist item, but not yet. Bug fixes: 1. PWL could fail if there were duplicate points at the beginning. It still does, but gives a reasonable error message. 2. Some "dot commands" were ignored if there were spaces before the dot. This was particularly annoying if the line was supposed to be ".end" which should make it exit. It didn't, leaving it in interactive mode, a major annoyance in a script. Other improvements: 1. There is a change to the way integration in capacitors is done. It is now strictly based on charge (i = dq/dt). The old version was based on capacitance (i = C * dv/dt) which is strictly incorrect. The dC/dt term was missing (i = C * dv/dt + v * dC/dt). This is a non-issue when C is constant. 2. More documentation on internals. Changes that I think are improvements, but some may disagree: 1. The command line is a little different. In the old version, "acs file" would run it, and whether it exited or not depended on whether there was an ".end" line. Now, by default, it just loads the file in preparation for interactive use. If you want batch mode, say "acs -b file". 2. The regression suite is included in the standard distribution. Changes that are not really improvements: 1. Due to the model compiler, the build process is a little more complicated. To do a complete build, you must build the model compiler first, then the simulator. If you are not making any new models, you can probably get away with just building the simulator. This will change in a future release. Bugs: 1. The transmission line initial conditions are not propagated until the transient analysis runs. 2. The makefile does not set up the proper link for the model compiler. You need to do it manually. ------------------------------------------------------------------ ACS 0.26 release notes (02/02/2000) New features: 1. BSIM1, BSIM2 models -- DC only. They work for AC and transient analysis, but only the DC effects actually work. The next release should have the charge effects. 2. New elements: trans-capacitor voltage controlled capacitor voltage controlled conductance voltage controlled resistor This is a side effect of the BSIM work. 3. Optional new syntax, with type first so component labels can start with any letter, and the choice of components is no longer limited by the 26 letters. This was necessary for a clean syntax for #2. 4. Some new parameters on existing devices, also a side effect of the BSIM work. 5. The manual in HTML form. The manual source is still in LaTeX, which can be used to generate HTML, PDF, Postscript, or many other formats. Bug fixes: 1. An error causing truncation error to be underestimated has been fixed. Other improvements: 1. MOSFET model evaluation is a little faster, due to use of one of the new elements to replace several old ones. I have seen 40%, but 20% is more likely. The improvement is most evident on busy circuits, where the ACS speed enhancements based on latency exploitation contribute more overhead than their value, that is .. the type of circuit that has run faster in Spice than ACS. 2. More documentation on internals. Changes that I think are improvements, but some may disagree: 1. Truncation error based step control is disabled when Euler's method is selected. The justification for this is that the reason for selecting Euler's method is to avoid the artifacts of high order methods on "stiff" poles. Without this change, a "stiff" pole would cause an unreasonably small step size. This did not appear to be much of a problem in the old release because the use of an incorrect formula for estimating truncation error. A "stiff" pole is one that has a response so fast it can be thought of as instantaneous. 2. The "help" command, with its 4 year old help file, has been removed. The concept is really obsolete. With the HTML form of the manual, a full online manual is a better replacement. ------------------------------------------------------------------ ACS 0.25 release notes (11/04/99) New features: None! Bug fixes: 1. A name conflict that caused compile to fail with gcc 2.95 has been fixed. 2. A problem that caused switches to lose state when a simulation is stopped and restarted when a switch is in transition has been fixed. 3. Two unrelated problems with transmission lines have been fixed. (Short lines and lines in subcircuits.) Changes that may or may not be improvements: 1. Several queues have been added, to manage model evaluation scheduling. This is part of work on multi-rate and mixed-mode simulation, and it replaces the traditional bypass scheme. In this release, probably the only noticeable difference will be that it runs a little faster. Known bugs: 1. The help file has not been updated for 4 years. ------------------------------------------------------------------ ACS 0.24 release notes (08/21/99) New features: 1. Enhanced (now documented) behavioral modeling. 2. Transmission line in transient analysis. 3. More documentation of internals. 4. Better batch mode error handling. Bug fixes: 1. Control-C trap works. 2. A bug that could cause a crash when a device had an improper number of nodes has been fixed. It now issues a warning, and grounds the unspecified nodes. 3. A bug that could cause a crash when a model or subcircuit is deleted then accessed has been fixed. 4. A scoping bug that sometimes put subckt parts in the root circuit has been fixed. 5. A bug in "fanout" that listed internal subckt nodes incorrectly has been fixed. Changes that may or may not be improvements: 1. "Make2" files for some systems have been removed. These have not been tested in years, and ACS and the compilers have both evolved significantly, so any portability patches that old are probably completely wrong now. Known bugs: 1. The help file has not been updated for 4 years. ------------------------------------------------------------------ ACS 0.23 release notes (06/15/99) New features: 1. Level 6 mos model. 2. HSpice style PWL and POLY(1). 3. "Table" behavioral modeling function. 4. Mixed-mode digital initialization. The bug fixes: 1. The alarm range worked backwards, now fixed. 2. Keep track of commons better. 3. Improved mixed-mode simulation. It still has not been tested as well as I would like, but is better. Digital initialization works now. 4. Another case of "zero time step" has been fixed. This one was relatively benign, in that it only caused a single extra full evaluation, with immediate recovery to a normal step size. 5. "Z" probe gave wrong results when probing a voltage source. Other improvements: (?) 1. Some subtractions now de-noise the result, eliminating the tiny numbers that result from subtracting two nearly equal numbers. The threshold can be set by the option "roundofftol". It is best left set at 1e-13. This improves speed slightly because 0 will prevent a matrix reload, but any non-zero number will not. It improves convergence slightly because the tiny numbers (which result from numerical problems) tend to cause further numerical problems. These tiny numbers are an artifact of the machine math, and vary depending on optimization and machine implementation details. 2. MOS temperature effects are computed at run time, instead of at load time, so you can change the temperature after loading and get correct results. 3. The options for integration method have changed, and are more flexible. The default is still trapezoidal, but that may change in a future release. You can specify the mode individually for capacitors and inductors. The information is in the data structure for all components, but it isn't always parsed. A future release will let you specify it by component or by model. The names are Spectre compatible, not Spice compatible, because it is more flexible. The Spice names are accepted, but may not act the same as they do in Spice. Choices are: unknown, euler, euleronly, trap, traponly. Options accepted and coerced into something else are: gear2, gear2only, trapgear, trapeuler. In general, gear is treated as euler, and each element will use either euler or trap. The device choice wins over the option command choice, but "only" wins over non-only. 4. Logic device syntax is changed. There are two more nodes, so power, ground, and enable are passed in. Power and enable are not used (except possibly in subckt models) but are required for consistency. 5. In many (not all) cases, arbitrary limits, due to fixed size arrays, have been removed. 6. More rigorous testing. I actually have a regression suite now. It is still not rigorous enough. 7. More rigorous convergence criteria. This should solve some of the false convergence problems. ACS convergence criteria has always been more rigorous than Spice. The cosmetic changes: 1. Convert most containers to STL. 2. Complete migration to the "common" tree, and eliminating reference to the old C "x" structure extensions. 3. Rearrangement of MOS model hierarchy, to make it easier to install other models. (BSIM family is coming.) ------------------------------------------------------------------ ACS 0.22 release notes (10/16/98) This release contains a few bug fixes, and a few cosmetic changes to the code. The bug fixes: 1. Fixes convergence failures in circuits with linear inductors, linear mutual inductors, and linear current controlled sources. 2. Fixes a bypass problem, which shows as transient analysis failure with the message "very backward time step". 3. Failed assertion on switch. The cosmetic changes: 1. The "OMSTREAM" class, as a step in migrating the i/o to C++ style. 2. A cleaner event queue, using a generic heap class. That's really all. I have not been actively working on ACS, mostly due to employment at a semiconductor company in their "corporate CAD" department. This will change soon, because my new employer (a CAD tool vendor) says it is ok to work on ACS. ------------------------------------------------------------------ ACS 0.21 release notes (03/30/96) There are several changes, most of which are only visible in subtle ways from the outside. 1. The code is more conformant with the upcoming standard, particularly in the use of complex, templates, lifetime of temporaries, and for scope. This should fix problems compiling with g++ 2.7. 2. Element commons are freed properly. 3. The manner in which elements are loaded into the matrix is different, and should be faster for large circuits with latency. Model bypass is more complete, because it is no longer necessary to do anything with a latent model. It makes little difference for small circuits, and circuits that are mostly active. Speed gains on small circuits are offset by #4. 4. The bypass criteria are more strict. It was possible to get incorrect results through interaction between model evaluation bypass and iteration damping. This release will not bypass anything when damping is in effect. There is a slight speed penalty. 5. Logic devices work even when there is no analog model. The bug causing a failure in this case has been fixed. The "bug" (that could in a twisted sense be called a feature) that leads to random mapping on start-up is still there. The logic model still needs work. 6. The code is somewhat more object-oriented. Some classes have been changed to be more general. ------------------------------------------------------------------ ACS 0.20 release notes (11/22/95) This release adds the level-3 MOSFET model. It is Spice compatible. Actually, it was there a long time ago but was removed because it didn't work correctly. This one has been tested and seems to match Spice results, and have convergence characteristics a little better than Spice 2g6. Like the level 1 and 2 models, only Meyer's capacitance model is implemented. (like Spice 3). ------------------------------------------------------------------ ACS 0.19 release notes (10/31/95) This release offers "improved" convergence. Several new options have been added to control iteration damping. In some cases, the program will take a partial step in an attempt to tame the wild fluctuations that can occur during iteration with Newton's method. This version appears to be considerably more robust than Spice 2g6. Several test circuits that fail to converge on Spice do converge on ACS. The cost of this is sometimes slower convergence. It generally takes about 2 more iterations per step than the previous version. This can be turned off, using the "dampstrategy" option at a slight cost in robustness. See the manual on the options command for more information. ------------------------------------------------------------------ ACS 0.18 release notes (05/12/95) This release offers improved memory management and exception handling, primarily aimed at MSDOS systems. Bug fixes: 1. For all ... Out of memory exceptions are properly trapped. Version 0.17 would crash if it ran out of memory. Now you get a reasonable message. It was only a real problem on MSDOS systems. 2. MSDOS floating point exceptions are trapped. In 0.17, underflow exceptions and null floating point exceptions could sometimes cause an abort. I don't know why, but the 80287 can generate a null exception when apparently nothing is wrong. 3. MSDOS only: Evade underflow in exp(). A large negative argument to exp can give bogus results. This was a known (to me) in Microsoft C 5.1. Apparently Borland has the same behavior. It may be a hardware problem. The fix is to not call exp with an argument beyond -200, and return 0 instead. 4. Don't use "-fast-math" with g++. (Makefile change). It doesn't make any difference in speed, and it sometimes causes problems, particularly the one in #3 above. Performance improvements: 1. Most elements no longer store values from the past. Only inductors and capacitors do. This means that some probes are no longer available. Some other data has been moved to improve memory usage. This change increases the capacity of the MSDOS version by about 10 transistors. Unix systems will swap less. Other visible changes: 1. The method of attaching models to devices has been changed, to improve maintainability. There are a few noticeable side effects. a. The default models -d-, -n- are no longer available. These were not documented. b. Model names must now be unique. If you have a diode model named "foo", you may not also have a mosfet model named "foo". c. A diode can reference a mosfet model. The diode will be equivalent to the source-bulk diode in the mosfet. This is a byproduct of using C++ derived classes. The mosfet model is derived from the diode model. 2. Exception handling in batch mode is different. It is still not right. ------------------------------------------------------------------ ACS 0.17 release notes (04/21/95) The primary difference in this release is reorganization and C++. A side benefit is that it is slightly faster, and uses slightly less memory. (The program is bigger, but it stores data more efficiently, for a net improvement.) It is a transitional release, with some of the code still in C. I hope to have a full C++ version this summer. Bug fixes: 1. Voltage source (vs, vcvs, ccvs) probes (current, power, etc.) now really work. 2. Fixed bug that caused strange results with mutual inductance after other parts of the circuit are changed. 3. Fixed memory leak in subcircuits and complex devices. 4. Fixed bug that caused a crash when probed elements were deleted. ------------------------------------------------------------------ ACS 0.16 release notes (12/10/94) New features: 1. New components: current controlled switch, current controlled current source, current controlled voltage source. Any simple two terminal element (not a diode) can be used as a probe, not just a voltage source. 2. Diode transit time parameter works. 3. Mutual inductance. The coupled coils must be linear. Only pairs of coupled inductors are supported in this release. A future release will probably support multiply coupled inductors. Bug fixes: 1. Continuing a transient analysis now works as documented. ------------------------------------------------------------------ ACS 0.15 release notes (07/31/94) Version 0.15 is supposed to be a minimal bug fix release to 0.14, but does have one new component. 1. Some additional ports are supported, including VMS. An HP port is supplied as a user contribution, but I have not tested it. 2. New component: voltage controlled switch. Spice-3 compatible. 3. Fixed bug that caused unpredictable behavior (usually loss of a probe, sometimes a crash) after replacing a component. 4. Fixed bug that caused incorrect evaluation and initialization of logic devices when there is no analog model. 5. Fixed a bug in truncation error control that sometimes caused it to become a no-op. It still seems to usually work the same as Spice, except that ACS will actually use at least the time steps you ask for. Spice will pick all the steps and interpolate for the points you ask for. This will usually cause ACS to use more time steps than Spice, hence often slower simulations. 6. Fixed another bug in truncation error that sometimes caused a divide by zero. ------------------------------------------------------------------ ACS 0.14 release notes (07/05/94) Version 0.14 was supposed to be a minimal bug fix release to 0.13. The same bugs are still there and there are a few small additions mostly aimed at coping with convergence problems. 1. The truncation error formula was changed to use the third derivative of charge instead of the second derivative of current. These two numbers are theoretically equal, but in practice they are not. The second derivative of current uses 3 terms to compute by divided differences. The third derivative of charge uses 4 terms. Using the odd number of terms catches the error due to the oscillatory nature of the trapezoid rule. An even number of terms tends to lose this error. Also, using charge tends to mask it. So, I have changed it to a less accurate, more optimistic method, the same as Spice. It now seems to work about the same as Spice, in the sense that it usually chooses about the same step sizes. Strictly, the old method is "better" but it tends to run away on stiff poles, trying for excess accuracy that doesn't matter. Your comments on this matter are welcome. If you know of any good papers on this, please let me know. 2. The "stiff" option has been removed from the transient command. Instead, use the .options "trapezoid" or "gear". For now, "gear" implies first order and is equivalent to the old "stiff". (A cop-out.) Actually, for stiff poles you want a first order method because the error is lower. 3. You can specify the integration method individually on any capacitor or inductor. 4. A bug causing the MSDOS version (2 byte integers) to mess up probes of other than nodes was fixed. 5. A bug that sometimes caused it to perpetually repeat the same time step was fixed. (SPICE would have reported "time step too small" and stopped.) 6. A bug that messed up step control when a dormant model wakes up and finds out it has been sleeping too long has been fixed. 7. "Mosflags" and "diodeflags" are different and there are more of them. There are lots of them and they may be useful in taming convergence problems. They control the heuristics that are applied when there appears to be a convergence problem. I have yet to find a circuit that could not be made to converge by judicious application of the flags and options, but any one setting is no better than Spice, and many are worse. One combination of flags gives Spice style limiting, which more often than not makes convergence worse. 8. "vmax" and "vmin" options as part of convergence heuristics. The default value of "limit" now large enough to essentially remove it. These limits sometimes help convergence, but more often hurt. 9. The "damp" option actually works. 10. The diode "off" flag works correctly. 11. There is a new command "alarm" that prints a message when a value exceeds a range. The syntax is the same as the "plot" command. ------------------------------------------------------------------ ACS 0.13 release notes (03/11/94) Version 0.13 adds several new features and has several bug fixes and performance improvements. 1. Fourier analysis really works. The "Fourier" command does a transient analysis but prints the results in the frequency domain. It is similar to the Spice command of the same name but not exactly the same. It is significantly more accurate than Spice because the transient time steps are chosen for the best match to the Fast Fourier Transform. Considerably more flexibility is available than in Spice. 2. Transient time step control by truncation error (finally). 3. Several options have been added to display diagnostics. 4. Fixed the default value for idsat, issat, ad, and as in the mos-diode. In 0.12, the default area was 1 square meter, which gave mosfet capacitors in the 500 uf range. This sometimes caused strange results. 5. Added some node probes, mostly for diagnostic use. 6. Fixed the "F" probe on linear elements. (Capacitor charge, inductor flux, admittance current, resistor voltage) It used to give an obviously bogus answer. Other changes: 1. Some general changes in the interest of improving code quality in general. 2. Function headers are in ANSI style, rather than K&R style. This version will compile as either C or C++. Future versions will require a C++ compiler. ------------------------------------------------------------------ ACS 0.12 release notes (10/09/93) Version 0.12 is a maintenance release. It adds no features (except Ultrix support) but fixes several bugs and changes some porting details. It should be easier to port this version than previous versions. The bug fixes are significant enough that you should upgrade to 0.12 even if you are not having any problems. ------------------------------------------------------------------ ACS 0.11 release notes (07/26/93) Version 0.11 fixes a few bugs in 0.10. 0.10 was supposed to be posted on alt.sources but due to a problem with the feed it never happened. New features: 1. New MOSFET and diode probes. All information available from the Spice 2 "op" analysis is now available as probes. For MOSFET these include cbd, cbs, cgsovl, cgdovl, cgbovl, cgs, cgd, cgb, vdsat, vth. Other (non-spice) new probes include cgst, cgdt, cgbt. (cgst = Cgs total = cgsovl + cgs.) These were available before by probing the value of the internal element but it was less convenient. Now it is simple and has the same name as in Spice. These probes are also available in transient analysis, so you can see (for example) the dynamic variations in capacitance. Bugs fixed: 1. Pass arguments to tr_volts and family by pointer instead of the whole structure. This is less likely to tickle a bug in Microsoft C. The MSDOS version of ACS 0.10 crashed frequently due to this bug. (Strictly, this is a Microsoft-C bug, not an ACS bug but the effect is the same.) 2. The AC "Z" probes work again. They were broken in 0.10. 3. The size of the buffer for text plots is increased allowing support for wider screens. The old version would crash if you did plots with outwidth set to wider than 128. The fix is to make it bigger, with a new constant MAXWIDTH, and trap the width setting bigger than MAXWIDTH. The current max is 256 for MSDOS and 512 for unix. The plotting code should probably be redone. 4. Width is narrower by 1 so setting width to 80 won't leave blank lines on an 80 column screen. 5. MOSFET capacitance now matches Spice (Meyer model) 6. Level 1 model linear region gds calculation was wrong, but close enough to often go unnoticed. It is correct and matches Spice now. 7. The value of an AC source now is compatible with Spice. That is, plain value is the DC-tran value. In old versions of ACS a plain value applied to all analyses including AC. You needed to prefix the value with "DC" to make it not apply to AC. Actually, it worked as documented. Now it works like Spice, which makes more sense. This was a major source of strange results in AC analysis. ------------------------------------------------------------------ ------------------------------------------------------------------ INSTALL000066400000000000000000000224321145401216200121060ustar00rootroot00000000000000Installation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. (Caching is disabled by default to prevent problems with accidental use of stale cache files.) If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You only need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not support the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Here is a another example: /bin/bash ./configure CONFIG_SHELL=/bin/bash Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent configuration-related scripts to be executed by `/bin/bash'. `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. Makefile.am000066400000000000000000000002161145401216200131050ustar00rootroot00000000000000## $Id$ ## ## Top level automake file for gnucap SUBDIRS= doc examples modelgen src EXTRA_DIST= autogen.sh Makefile.template configure.old Makefile.in000066400000000000000000000521161145401216200131240ustar00rootroot00000000000000# Makefile.in generated by automake 1.11 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ depcomp install-sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir dist dist-all distcheck ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d "$(distdir)" \ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr "$(distdir)"; }; } am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EXEEXT = @EXEEXT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MODELGEN = @MODELGEN@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = doc examples modelgen src EXTRA_DIST = autogen.sh Makefile.template configure.old all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @$(am__cd) '$(distuninstallcheck_dir)' \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ ctags-recursive install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \ distclean distclean-generic distclean-hdr distclean-tags \ distcleancheck distdir distuninstallcheck dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: Makefile.template000066400000000000000000000021061145401216200143230ustar00rootroot00000000000000# SDB changed configure and Makefile operation in -*- Makefile -*- # the following way: The configure script now # copies the subdir Makefiles over to Makefile.original, # and then uses sed to put the --prefix target into # Makefile. # Use the target "unconfig" to move Makefile.original # back to Makefile. all: modelgen gnucap modelgen: nothing (cd modelgen; ${MAKE} -k) gnucap: modelgen (cd src; ${MAKE} -k) man: nothing (cd man; ${MAKE} -k) debug: (cd modelgen; make debug) (cd src; make debug) clean: (cd man; make clean) (cd modelgen; make clean) (cd src; make clean) -rm *~ \#*\# # This moves Makefile.original back to Makefile. unconfig: (cd modelgen; make unconfig) (cd src; make unconfig) # (cd man; make unconfig) # This creates Makefile.original, and then assembles # Makefile. install: nothing (cd src; make install) # This simply erases the executable from the directory # specified in Makefile. uninstall: nothing (cd src; make uninstall) manifest: (cd modelgen; make manifest) (cd src; make manifest) # (cd man; make manifest) nothing: NEWS000066400000000000000000000000001145401216200115370ustar00rootroot00000000000000README000066400000000000000000000034461145401216200117410ustar00rootroot00000000000000Readme for development snapshot 2007-02-21 This is a development snapshot. As such, there may be problems due to new work. The most important change here is enhanced plugin support, and the 3 new model packages, distributed separately. Also, commands use the dispatcher, so they can be added as plugins. Readme for development snapshot 2006-12-04 This is a development snapshot. As such, there may be problems due to new work. New features: "attach" and "detach" commands, for attaching and detaching compiled modules. To use .... Start with a .model file. Compile it ..... >> gnucap-modelgen my-model.model .. produces my-model.h amd my-model.cc Compile that, with "-fPIC -shared" options >> g++ -fPIC -shared my-model.cc .. produces a.out (you could name it with -o ..) Now, run gnucap >> gnucap (signs on..) then you can attach the model.. gnucap> attach ./a.out gnucap> .. now you can use your model!! This snapshot includes some new verilog code, which is incomplete and not ready for anyone but a developer. You can safely ignore it for now. It also changes the way models, devices, and functions are dispatched. The new version uses a dispatcher object, that is built on start-up, based on what modules are linked. Models, devices, and functions can be added simply by linking them in. There is no need to change anything else. Likewise, if you don't need a model, device, or function, and want a version with it missing, just remove it from "Make1" and relink. The latest "stable" version is 0.35. If you want to help development, use this snapshot and tell us what you find. If you don't want to live on the edge, use the stable version. If you are making binary packages for distribution, please try this version and let me know how it works, but continue to distribute 0.35. aclocal.m4000066400000000000000000001076551145401216200127300ustar00rootroot00000000000000# generated automatically by aclocal 1.11 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],, [m4_warning([this file was generated for autoconf 2.65. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.11], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.11])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 9 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 10 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. #serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 16 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The `parallel-tests' driver may need to know about EXEEXT, so add the dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless `enable' is passed literally. # For symmetry, `disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful (and sometimes confusing) to the casual installer], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 6 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR autogen.sh000077500000000000000000000007711145401216200130600ustar00rootroot00000000000000#! /bin/sh # # $Id$ # # Run the various GNU autotools to bootstrap the build # system. Should only need to be done once. # for now avoid using bash as not everyone has that installed CONFIG_SHELL=/bin/sh export CONFIG_SHELL echo "Running aclocal..." aclocal $ACLOCAL_FLAGS || exit 1 echo "Running autoheader..." autoheader || exit 1 echo "Running automake..." automake -a -c --gnu || exit 1 echo "Running autoconf..." autoconf || exit 1 echo "not Running configure..." ##./configure $@ || exit 1 config.h.in000066400000000000000000000015601145401216200130770ustar00rootroot00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the `dl' library (-ldl). */ #undef HAVE_LIBDL /* Define to 1 if you have the `readline' library (-lreadline). */ #undef HAVE_LIBREADLINE /* Define to 1 if you have the `termcap' library (-ltermcap). */ #undef HAVE_LIBTERMCAP /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Version number of package */ #undef VERSION configure000077500000000000000000004225721145401216200127750ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.65. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error ERROR [LINENO LOG_FD] # --------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with status $?, using 1 if that was 0. as_fn_error () { as_status=$?; test $as_status -eq 0 && as_status=1 if test "$3"; then as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 fi $as_echo "$as_me: error: $1" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= ac_unique_file="src/main.cc" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS MODELGEN am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CXX CPPFLAGS LDFLAGS CXXFLAGS CXX MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_maintainer_mode enable_debug enable_dependency_tracking with_readline ' ac_precious_vars='build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS LIBS CPPFLAGS CCC' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error "unrecognized option: \`$ac_option' Try \`$0 --help' for more information." ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer --enable-debug Enable building of debug code. [default: disabled] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-readline support command line editing [default=yes] Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.65 Copyright (C) 2009 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_link cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.65. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then ac_site_file1=$CONFIG_SITE elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # this is any file in the source directory # used as a check to be sure we found it am__api_version='1.11' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do for ac_t in install-sh install.sh shtool; do if test -f "$ac_dir/$ac_t"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/$ac_t -c" break 2 fi done done if test -z "$ac_aux_dir"; then as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test "${ac_cv_path_mkdir+set}" = set; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AWK+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE=gnucap VERSION=2009-12-07 cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' ac_config_headers="$ac_config_headers config.h" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE { $as_echo "$as_me:${as_lineno-$LINENO}: checking if debug code should be compiled in" >&5 $as_echo_n "checking if debug code should be compiled in... " >&6; } # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : enableval=$enable_debug; if test "X$enable_debug" = "Xno" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } enable_debug=yes fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } enable_debug=no fi # Checks for programs. ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 $as_echo_n "checking whether the C++ compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { as_fn_set_status 77 as_fn_error "C++ compiler cannot create executables See \`config.log' for more details." "$LINENO" 5; }; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 $as_echo_n "checking for C++ compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot compute suffix of object files: cannot compile See \`config.log' for more details." "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi # If we are cross compiling, then we need to search for a # gnucap-modelgen program to use for our build. This can # either be an installed modelgen or it can be specified # like: # env MODELGEN=/build/i686--linux/modelgen/gnucap-modelgen /srcs/gnucap/configure # --host=alpha--netbsd --build=i686--linux # if test "$cross_compiling" = yes; then # Extract the first word of "gnucap-modelgen", so it can be a program name with args. set dummy gnucap-modelgen; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_MODELGEN+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MODELGEN in [\\/]* | ?:[\\/]*) ac_cv_path_MODELGEN="$MODELGEN" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MODELGEN="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi MODELGEN=$ac_cv_path_MODELGEN if test -n "$MODELGEN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MODELGEN" >&5 $as_echo "$MODELGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MODELGEN=../modelgen/gnucap-modelgen fi # for building the documentation #AC_PATH_PROG(DVIPDFM, dvipdfm, notfound) #AM_CONDITIONAL(MISSING_DVIPDFM, test x$DVIPDFM = xnotfound) #AC_PATH_PROG(HACHA, hacha, notfound) #AC_PATH_PROG(HEVEA, hevea, notfound) #AM_CONDITIONAL(MISSING_HEVEA, test x$HEVEA = xnotfound -o x$HACHA = xnotfound) #AC_PATH_PROG(LATEX, latex, notfound) #AC_PATH_PROG(MAKEINDEX, makeindex, notfound) #AM_CONDITIONAL(MISSING_LATEX, test x$LATEX = xnotfound -o x$MAKEINDEX = xnotfound) # Checks for libraries. # this is a c++ program so use c++ for the tests ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu #AC_CHECK_LIB([termcap], [main]) #AC_CHECK_LIB([readline], [main]) # Check whether --with-readline was given. if test "${with_readline+set}" = set; then : withval=$with_readline; else with_readline=yes fi if test "x$with_readline" != xno ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ltermcap" >&5 $as_echo_n "checking for main in -ltermcap... " >&6; } if test "${ac_cv_lib_termcap_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltermcap $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_termcap_main=yes else ac_cv_lib_termcap_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_termcap_main" >&5 $as_echo "$ac_cv_lib_termcap_main" >&6; } if test "x$ac_cv_lib_termcap_main" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBTERMCAP 1 _ACEOF LIBS="-ltermcap $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lreadline" >&5 $as_echo_n "checking for main in -lreadline... " >&6; } if test "${ac_cv_lib_readline_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_readline_main=yes else ac_cv_lib_readline_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_main" >&5 $as_echo "$ac_cv_lib_readline_main" >&6; } if test "x$ac_cv_lib_readline_main" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBREADLINE 1 _ACEOF LIBS="-lreadline $LIBS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" fi # Checks for header files. #AC_CHECK_HEADERS([fcntl.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. if test "$enable_debug" = "yes" ; then CPPFLAGS="$CPPFLAGS -DTRACE_UNTESTED" else CPPFLAGS="$CPPFLAGS -DNDEBUG" fi # if we have gcc and we've asked for debugging then add lots of -W if test "x$GCC" = "xyes" -a "$enable_debug" = "yes"; then for flag in -DTRACE_UNTESTED -Wall -W -Wno-sign-compare \ -Wpointer-arith -Wcast-qual \ -Wwrite-strings -Wconversion \ -Woverloaded-virtual -O2 -Wlong-long \ -Wsign-compare -Wcast-align ; do case " ${CFLAGS} " in *\ ${flag}\ *) # flag is already present ;; *) CFLAGS="$CFLAGS ${flag}" ;; esac case " ${CXXFLAGS} " in *\ ${flag}\ *) # flag is already present ;; *) CXXFLAGS="$CXXFLAGS ${flag}" ;; esac done fi # exports symbols to plugins LDFLAGS="$LDFLAGS -rdynamic" #AC_OUTPUT([ # Makefile # doc/Makefile # examples/Makefile # man/Makefile # man/Addmodel/Makefile # man/Behavior/Makefile # man/Circuit/Makefile # man/Commands/Makefile # man/Tech/Makefile # modelgen/Makefile # src/Makefile # ]) ac_config_files="$ac_config_files Makefile doc/Makefile examples/Makefile modelgen/Makefile src/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error ERROR [LINENO LOG_FD] # --------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with status $?, using 1 if that was 0. as_fn_error () { as_status=$?; test $as_status -eq 0 && as_status=1 if test "$3"; then as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 fi $as_echo "$as_me: error: $1" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.65. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.65, with options \\"\$ac_cs_config\\" Copyright (C) 2009 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; "modelgen/Makefile") CONFIG_FILES="$CONFIG_FILES modelgen/Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || as_fn_error "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_t=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_t"; then break elif $ac_last_try; then as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ || as_fn_error "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ || as_fn_error "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ || as_fn_error "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit $? fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ** Configuration summary for $PACKAGE $VERSION: prefix: $prefix CPPFLAGS: $CPPFLAGS CFLAGS: $CFLAGS CXXFLAGS: $CXXFLAGS LDFLAGS: $LDFLAGS LIBS: $LIBS " >&5 $as_echo " ** Configuration summary for $PACKAGE $VERSION: prefix: $prefix CPPFLAGS: $CPPFLAGS CFLAGS: $CFLAGS CXXFLAGS: $CXXFLAGS LDFLAGS: $LDFLAGS LIBS: $LIBS " >&6; } configure.ac000066400000000000000000000105321145401216200133410ustar00rootroot00000000000000# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. # $Id$ # # COPYRIGHT # # Copyright (C) 2005, 2006 Dan McMahill # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. AC_PREREQ(2.59) AC_INIT([src/main.cc]) # this is any file in the source directory # used as a check to be sure we found it AM_INIT_AUTOMAKE(gnucap, 2009-12-07) AM_CONFIG_HEADER([config.h]) AM_MAINTAINER_MODE AC_MSG_CHECKING([if debug code should be compiled in]) AC_ARG_ENABLE([debug], [ --enable-debug Enable building of debug code. [[default: disabled]]], [ if test "X$enable_debug" = "Xno" ; then AC_MSG_RESULT([no]) else AC_MSG_RESULT([yes]) enable_debug=yes fi ], [ AC_MSG_RESULT([no]) enable_debug=no ]) # Checks for programs. AC_PROG_CXX # If we are cross compiling, then we need to search for a # gnucap-modelgen program to use for our build. This can # either be an installed modelgen or it can be specified # like: # env MODELGEN=/build/i686--linux/modelgen/gnucap-modelgen /srcs/gnucap/configure # --host=alpha--netbsd --build=i686--linux # if test "$cross_compiling" = yes; then AC_PATH_PROG(MODELGEN, gnucap-modelgen) else MODELGEN=../modelgen/gnucap-modelgen AC_SUBST([MODELGEN]) fi # for building the documentation #AC_PATH_PROG(DVIPDFM, dvipdfm, notfound) #AM_CONDITIONAL(MISSING_DVIPDFM, test x$DVIPDFM = xnotfound) #AC_PATH_PROG(HACHA, hacha, notfound) #AC_PATH_PROG(HEVEA, hevea, notfound) #AM_CONDITIONAL(MISSING_HEVEA, test x$HEVEA = xnotfound -o x$HACHA = xnotfound) #AC_PATH_PROG(LATEX, latex, notfound) #AC_PATH_PROG(MAKEINDEX, makeindex, notfound) #AM_CONDITIONAL(MISSING_LATEX, test x$LATEX = xnotfound -o x$MAKEINDEX = xnotfound) # Checks for libraries. # this is a c++ program so use c++ for the tests AC_LANG([C++]) #AC_CHECK_LIB([termcap], [main]) #AC_CHECK_LIB([readline], [main]) AC_ARG_WITH([readline], [AS_HELP_STRING([--with-readline], [support command line editing @<:@default=yes@:>@])], [], [with_readline=yes]) if test "x$with_readline" != xno ; then AC_CHECK_LIB([termcap], [main]) AC_CHECK_LIB([readline], [main]) fi AC_CHECK_LIB([dl], [dlopen]) # Checks for header files. #AC_CHECK_HEADERS([fcntl.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. if test "$enable_debug" = "yes" ; then CPPFLAGS="$CPPFLAGS -DTRACE_UNTESTED" else CPPFLAGS="$CPPFLAGS -DNDEBUG" fi # if we have gcc and we've asked for debugging then add lots of -W if test "x$GCC" = "xyes" -a "$enable_debug" = "yes"; then for flag in -DTRACE_UNTESTED -Wall -W -Wno-sign-compare \ -Wpointer-arith -Wcast-qual \ -Wwrite-strings -Wconversion \ -Woverloaded-virtual -O2 -Wlong-long \ -Wsign-compare -Wcast-align ; do case " ${CFLAGS} " in *\ ${flag}\ *) # flag is already present ;; *) CFLAGS="$CFLAGS ${flag}" ;; esac case " ${CXXFLAGS} " in *\ ${flag}\ *) # flag is already present ;; *) CXXFLAGS="$CXXFLAGS ${flag}" ;; esac done fi # exports symbols to plugins LDFLAGS="$LDFLAGS -rdynamic" #AC_OUTPUT([ # Makefile # doc/Makefile # examples/Makefile # man/Makefile # man/Addmodel/Makefile # man/Behavior/Makefile # man/Circuit/Makefile # man/Commands/Makefile # man/Tech/Makefile # modelgen/Makefile # src/Makefile # ]) AC_OUTPUT([ Makefile doc/Makefile examples/Makefile modelgen/Makefile src/Makefile ]) AC_MSG_RESULT([ ** Configuration summary for $PACKAGE $VERSION: prefix: $prefix CPPFLAGS: $CPPFLAGS CFLAGS: $CFLAGS CXXFLAGS: $CXXFLAGS LDFLAGS: $LDFLAGS LIBS: $LIBS ]) configure.old000077500000000000000000000016541145401216200135440ustar00rootroot00000000000000#!/bin/sh #--------------------------------------------------- # This stuff introduced by SDB to enable --prefix # at configure time # echo Input flag = $1 if test "x$1" != "x"; then # echo Found input parameter -- $1 # Now see if the parameter is --prefix= if test "x${1#--prefix=}" != "x$1"; then # echo "Found --prefix in input args. Setting prefix directory." prefix=${1#--prefix=} else # echo "Found unrecognized parameter in input args." # Just use the default prefix dir. prefix=/usr/local fi else # echo "No input parameter found." # Just use the default prefix dir prefix=/usr/local fi args="--prefix=$prefix" echo "Configuring gnucap using $args" #--------------------------------------------------- cp Makefile.template Makefile #echo man #(cd man; ./configure.old $args) echo modelgen (cd modelgen; ./configure.old $args) echo src (cd src; ./configure.old $args) echo done exit 0 depcomp000077500000000000000000000371001145401216200124300ustar00rootroot00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2005-07-09.11 # Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test -f "$tmpdepfile"; then : else stripped=`echo "$stripped" | sed 's,^.*/,,'` tmpdepfile="$stripped.u" fi if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then outname="$stripped.o" # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mecanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two # compilations output dependencies in in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: doc/000077500000000000000000000000001145401216200116175ustar00rootroot00000000000000doc/COPYING000066400000000000000000000431221145401216200126540ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. doc/INSTALL000066400000000000000000000050011145401216200126440ustar00rootroot00000000000000GnuCap 0.30 installation instructions (10/29/2001) For this version, you can use either the GNU style "configure;make" style build process, or the old ACS style. If it works for you, use the GNU style. For the GNU style build, just type "./configure" then "make" from the project's root directory. This will configure both the model compiler and the simulator, and then build the model compiler first, then use it to build the simulator. That should be all that is needed. You do not to read any further. It that doesn't work for you, a two step manual configuration may be required. First you build the model compiler, then you build the simulator. You can usually get away with only building the simulator. So .. cd to modelgen, type make (as below) then go back down and cd to src, type make (as below) If it fails, go into its build directory (the one containing the .o files) and manually create a symbolic link to the model compiler. "Type make" really means ...... Usually, you can just type "make". This will make a "release" version, with optimization on and extra debug code out. It will build in the O subdirectory. This assumes you have g++ in a reasonable configuration. To make a "debug" version (slow, with additional error checking), type "make debug". If you have a recent g++ compiler, this should build it in the O-DEBUG subdirectory. If your compiler is not g=++, but called by "CC", try "make CC". This is believed to work with some compilers. Some of them do not implement the full language, so they cannot be used. Try it. There is a special one "sun4-CC" for a Sun running Solaris with the most recent version of Sun's compiler. It will not work with older versions. To make a "release" version for a particular system, type make followed by your system type, such as "make linux". This will build it in a subdirectory (in this case LINUX). With this method, you can build for multiple systems in the same directory. Look at "Makefile" for a list of supported systems, and clues of how to do it on others. Most of them have not been tried in years. If it doesn't work, edit only a "Make2.*" file, and possibly md.h or md.cc. All nonportabilities are confined to these files. It does require a recent and proper C++ compiler with a proper library, including STL. Gnu compilers older than 2.8 will probably not work. Anything else that old will also probably not work. Any high quality C++ compiler available today should work. To install .... Just move or copy the executable to where you want it. doc/Makefile.am000066400000000000000000000003501145401216200136510ustar00rootroot00000000000000## $Id$ ## dist_man_MANS= gnucap.1 gnucap-ibis.1 pkgdocsdir= ${pkgdatadir}/doc dist_pkgdocs_DATA= \ acs-tutorial COPYING history INSTALL relnotes.029 \ relnotes.030 relnotes.031 relnotes.032 relnotes.033 relnotes.034 whatisit doc/Makefile.in000066400000000000000000000322721145401216200136720ustar00rootroot00000000000000# Makefile.in generated by automake 1.11 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = doc DIST_COMMON = $(dist_man_MANS) $(dist_pkgdocs_DATA) \ $(srcdir)/Makefile.am $(srcdir)/Makefile.in COPYING INSTALL ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(pkgdocsdir)" NROFF = nroff MANS = $(dist_man_MANS) DATA = $(dist_pkgdocs_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EXEEXT = @EXEEXT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MODELGEN = @MODELGEN@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ dist_man_MANS = gnucap.1 gnucap-ibis.1 pkgdocsdir = ${pkgdatadir}/doc dist_pkgdocs_DATA = \ acs-tutorial COPYING history INSTALL relnotes.029 \ relnotes.030 relnotes.031 relnotes.032 relnotes.033 relnotes.034 whatisit all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-man1: $(dist_man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list=''; test -n "$(man1dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } install-dist_pkgdocsDATA: $(dist_pkgdocs_DATA) @$(NORMAL_INSTALL) test -z "$(pkgdocsdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgdocsdir)" @list='$(dist_pkgdocs_DATA)'; test -n "$(pkgdocsdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdocsdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdocsdir)" || exit $$?; \ done uninstall-dist_pkgdocsDATA: @$(NORMAL_UNINSTALL) @list='$(dist_pkgdocs_DATA)'; test -n "$(pkgdocsdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(pkgdocsdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(pkgdocsdir)" && rm -f $$files tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(MANS) $(DATA) installdirs: for dir in "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(pkgdocsdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_pkgdocsDATA install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_pkgdocsDATA uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-dist_pkgdocsDATA install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-man1 \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ uninstall-dist_pkgdocsDATA uninstall-man uninstall-man1 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: doc/acs-tutorial000066400000000000000000000747111145401216200141630ustar00rootroot00000000000000Tutorial for acs V0.02 Copyright 1999 Telford Tendys >>> Introduction This is not an alternative to reading the acs manual. The manual is very nicely presented in LaTeX and you should print it out and keep it handy when working with acs. This document is organised starting from easy and working towards difficult and presumes that you have some idea of what electrical circuits are but don't know much about simulators. The acs manual is organised in alphabetical order and in groups of concepts and it presumes that you know SPICE already. >>> The basic concept of a nodal analysis. Using nodes is one way to describe a lumped element circuit. Lumped elements are used because there is no consideration of what is occuring inside a given component, only what is happening on the terminals of the component. For example, this analysis makes no attempt to find the voltage in the middle of a resistor, only at the ends of the resistor. The whole circuit model consists of ``nodes'' and ``components''. A node is (electrically speaking) a single point, it has exactly one voltage value at any given time value. A component will connect to two or more nodes (usually two) and represents some method by which the voltages at those nodes affect one another. Describing which components connect to which nodes will completely describe the structure of the circuit. One additional concept is a ``branch''. The current though a branch is the amount of current flowing from a node into a component that connects to that node. Some branch currents (such as the current through a voltage source) are explicitly calcualted, others (such as the current through a resistor) are implicitly calculated as a result of calculating the node voltages. >>> The basic concept of a circuit file. Tradition has it that acs input files have the extension ``.ckt''. The format is similar to that used by version 2 of the SPICE simulator; it is a line oriented format with items separated by whitespace. The overall file structure is: * Header line (first line of the file) contains the name of the circuit, traditionally in all capitals. * blank lines do nothing * comment lines are any line beginning with a star ``*''. These can be anywhere in the file except the header line. * component lines begin with a letter and represent some component that is in the circuit. The order that components are listed does not matter because the topology is described by the nodes that the components are connected to. * continuation lines begin with a plus ``+'' and continue the previous line so that long lines can be written neatly. * command lines begin with a dot ``.'' and are not considered to be part of the circuit, they cause the simulator to execute some analysis or change some options. They are also used to delimit special parts of the file such as subcircuits. >>> The simplest possible circuit file --------------------------------------------------------------------- eg1.ckt RESISTOR DRIVEN BY VOLTAGE SOURCE Vsupply 0 2 10 R1 0 2 1k ---------------------------------------------------------------------- This file defines a circuit containing two nodes and two components. The components have the names ``Vsupply'' and ``R1'', the first letter of the component name tells what that component is so ``Vsupply'' is a voltage source and ``R1'' is a resistor. Each component has a value, the voltage source is 10 volts and the resistor is 1000 ohms. The nodes have the numbers ``0'' and ``2''. Note that there is no node ``1'' but this doesn't matter, not every node number needs to be used. Like SPICE version 2 (but unlike version 3) nodes must be numbered in acs. In order to load this circuit into the simulator the following command would be used: acs eg1.ckt What happens is that acs loads in the circuit, finds no commands to execute (since this file has no command lines) and so enters interactive mode with a ``-->'' prompt. From the interactive mode it is possible to exercise the circuit model, firstly by putting a probe on the node that needs measuring (using the print statement) then by starting the simulation: print dc v(2) dc Needless to say, ``dc'' is a steady state direct current analysis and the ``print'' command used here is saying, ``when you do a DC analysis, tell me the voltage at node 2''. The result should be -10 volts. At first glance, it might seem like it should be 10 volts... but (same as SPICE) the voltage sources are listed with their positive terminal first, then their negative terminal. Node 0 is the ground node (or reference node) which is always 0 volts so node 2 is at -10 volts. Wiring ``Vsupply'' the other way around would change the answer to 10 volts. Things get trickier when dealing with current sources where the node at the tail end of the current source arrow is listed first (and called ``+'') and the pointy head end of the arrow is listed second (and called ``-''). Although this convention may seem disorienting to someone who was brought up testing their circuits with batteries or a bench power supply and poking their meter probes into things, it is a well established SPICE convention and probably never going to change. However, the voltage of the node may not be the answer required. What about the current going through the source? We can move our probe to look at current instead: print dc i(R1) i(Vsupply) dc Now we can see 10 milliamps going through both components, note the sign convention when probing current; once more this is something that you must simply learn, you might draw diagrams of the main components and mark the important conventions of [+] terminal, [-] terminal and current flow. You might also realise that this convention does have its own logical consistency which makes it easier to remember. For example, consider a resistor: the terminal called [+] is listed first and the internal current flow is positive when current flows into the [+] terminal, through the resistor and out of the [-] terminal. In the case of a resistor this sounds quite sensible because the [+] terminal WOULD be more positive when the current flows in this manner. The sources merely maintain the same convention as is applied to a resistor, what is important to remember is that [+] and [-] terminals are just names that provide a sign convention they don't insist that one terminal is a higher voltage than the other. This example should provide enough information for analysis of any network of voltage sources and resistors and for inspection of any current or voltage in such a circuit. The power and resistance of each component can be measured: print dc p(R1) p(Vsupply) r(R1) r(Vsupply) dc quit Note that the supply shows negative power to it is putting power into the system while the resistor shows positive power meaning that it is taking power out of the system. Also notice that the resistance measurement will attempt to find the resistance of the source without error but the resulting value is huge (this seems wrong, I would expect it to be zero). >>> Networks of Resistors and Sources The previous example covers enough concepts to model arbitrarily complex networks of resistors and sources. These are essentially linear circuits that have no relation to time. A more elaborate example is presented below: --------------------------------------------------------------------- eg2.ckt NETWORK OF RESISTORS AND VOLTAGE SOURCES V1 2 1 10 V2 4 3 5 V3 0 3 3 R1 1 2 220 R2 2 3 4.7k R3 4 5 3k3 R4 3 5 10k R5 0 1 22k R6 0 5 15k ---------------------------------------------------------------------- Run this with: acs eg2.ckt print dc v(1) v(2) v(3) v(4) v(5) dc quit Note that this is about the limit of what can be done with these two components. Other components that offer further possibilities are the current source (any component with a name that begins with ``I'' is a current source) and the dependent sources: first letter output input of name type type ----------------------------------------- E voltage voltage F current current G current voltage H voltage current ----------------------------------------- Each of these has a gain value expressing the relation between its output and its input and they allow the modeling of linear amplifiers and other such devices. As mentioned above, none of these components understand time nor can they be used to represent a nonlinear device. Thus, any network constructed from the components that have been seen so far will be reducible to a Thevenin or Norton equivalent circuit when considered from the point of view of one particular node and the ground node 0. --------------------------------------------------------------------- eg3.ckt NETWORK OF RESISTORS AND DEPENDENT SOURCES * * Reduce this complicated collection of dependencies * down to a single Thevenin equivalent between node 2 and * the ground node 0 * I1 1 4 2 V1 1 0 5 E1 5 2 1 3 0.4 F1 5 6 R1 3e-2 G1 2 3 4 6 1.3 H1 3 0 R3 1 R1 4 5 2.2 R2 1 2 470 R3 0 2 330 R4 3 6 1k R5 5 6 1e4 * * Look at the voltage at node 2 and the impedance looking into node 2 * .print dc v(2) z(2) .dc .end ---------------------------------------------------------------------- Notice that this example file contains some lines that begin with a dot. These are command lines and behave exactly like the commands you type in interactive mode. These command lines are dotted because of the old SPICE tradition of executing all of the component lines first and then the command lines, acs doesn't bother with this, it executes every line in the order that it sees them, but it still follows the old idea of dotting the command lines as a little tribute to SPICE and to make it easier to see what is going on when you read a .ckt file. When you run this example, you might try: acs eg3.ckt And (all going well) you will see that node 2 is equivalent to a source of 54.343 volts in series with an 0.83888 ohm resistor. You should also notice that acs never goes into interactive command mode. This is because of the ``.end'' command that tells acs to finish at this point. You may want to use this example circuit in interactive mode, to achieve this you could either delete the .end command, or (from the system prompt) type: acs get eg3.ckt Then you can use other interactive commands. Note that you can modify the circuit interactively too. Consider adding another resistor by typing the following at the acs interactive prompt: build R3 R6 3 4 12k Which allows you to adjust the topology of the circuit in memory. This includes adding components and modifying existing components. You can interactively remove components from the circuit using the ``delete'' command or you can wipe out the entire circuit using the ``clear'' command. To put the adjusted topology into a file you use the save command: save eg3_mod.ckt quit cat eg3_mod.ckt Looking at what you have saved you will probably notice a few things: firstly, acs has remembered your comment lines and command lines and saved them too; secondly, your extra line was inserted into the file before the line containing component ``R3'', this is caused by the argument on the ``build'' command and allows you to insert your build lines where you want them. >>> Things That Can Go Wrong --------------------------------------------------------------------- eg4.ckt VOLTAGE SOURCES IN PARALLEL V1 1 0 10.0 V2 1 0 10.2 .print dc v(1) i(V1) i(V2) .dc .end ---------------------------------------------------------------------- Here we have V1 and V2 both driving the same node at about 10 volts. Actually, V2 is very slightly higher than 10 volts so there will be some argument between V1 and V2 as to exactly what the final voltage at node 1 really is. You should see that huge currents are flowing through the supplies (10,000 amps) just due to this small voltage difference. Also note that acs does not throw in the towel and give up, nor does it fail to converge... the answer that it gets for v(1) is a compromise, halfway between the two sources. What is does is introduce a slight imperfection in the voltage sources so that they do have a small internal series resistor. This allows it to make the best guess that it can in a difficult situation. How much is this resistance? You can find out like so: acs options Look at the value of the option called ``short'' (near the middle of the block of options), this is the value (in ohms) of the internal resistance of a voltage source. The ``u'' character means ``micro'' or 1e-6 so the default value of a short circuit is 1e-5 ohms. You might decide that a different short circuit value is more appropriate for running the above circuit so you can type (from the acs prompt): options short=0.5 get eg4.ckt dc exit Which should show you the same voltage (10.1) but now the current has reduced to only one fifth of an Amp (still not small but a lot more reasonable if you were building this with real supplies). Other option values can be altered in much the same way and input files can contain ``.options'' command lines in order to set these options whenever the circuit is loaded. --------------------------------------------------------------------- eg5.ckt CURRENT SOURCES IN SERIES I1 0 1 2.0001 I2 1 0 2.0 .print dc v(1) i(I1) i(I2) .dc .end ---------------------------------------------------------------------- The case of putting two current sources in series is much the same concept as two voltage sources in parallel. However notice that acs copes with it in a different manner. It cannot find a compromise current that is partway between the two sources and it always gives a huge value for the voltage at node 1. At least it doesn't crash and it does give results that give some suggestion as to where the problem might be. There is no option that introduces resistance into a current source but you can explicitly add these resistors if you like by putting the resistor in parallel with the current source. What if you had a big, complex circuit, you messed up by putting two current sources in series but you never thought about checking the strange node? How would you ever know that the circuit was broken? Try this exercise: acs get eg5.ckt alarm dc v(*)(-1e3,1e3) dc quit Now you get a warning whenever any component gets more that 1000 volts across it. This can be used to test component breakdown if you know that you are using components that cannot tolerate high voltages. It can also be used to ensure that your simulated circuit stays within what you might expect to be the absolute maximum values. >>> Nonlinear Devices -- Diodes All of the previous circuits have been linear. This is to say that all the devices (voltage sources, current sources, dependent source and resistors) are linear devices and the overall ``shape'' of the problem does not change as the values of the system are scaled up or down. For example, if a circuit is solved once, then after that all of the voltage sources in the circuit are doubled, the circuit doesn't need to be solved a second time because all the node voltages will merely be double those of the first solution. Try it yourself if you disbelieve. Linear circuits also obey the principle of ``superposition'' which is to say that the circuit can be solved for each source separately and then all of those solutions can be added up to get the solution of a circuit containing many sources. A textbook in basic circuit theory will explain superposition in linear circuits and you can try working through the textbook examples on the simulator using what has been explained so far. At this point, we take the step into nonlinear circuits which do NOT obey superposition and do NOT scale. The most elementary nonlinear component is a diode. --------------------------------------------------------------------- eg6.ckt DIODE CASCADE .model 1N414 D IS=2e-14 Vcc 1 0 5 Dx 1 10 1N414 Dy 10 20 1N414 Dz 20 30 1N414 Rd1 10 0 1k Rd2 20 0 1k Rd3 30 0 1k .print dc v(10) v(20) v(30) .dc Vcc 0 5 0.5 >eg6.dat .end ---------------------------------------------------------------------- You can run this example and look at the results like so: acs eg6.ckt gnuplot set data style lines plot 'eg6.dat' using 1:2, 'eg6.dat' using 1:3, 'eg6.dat' using 1:4 exit You may not like using gnuplot and may prefer some other plotting program such as gwave or gle. Acs output can be used by most plotting programs in much the same manner as above by using the redirection arrow on the command that runs the simulation (``dc'' in this case). Note that it usually won't work to redirect the normal output to a file using your shell and then cut and paste that output into your plotting program because the normal output does not use standard scientific notation, using the internal redirection option provided by acs also guarantees you get a nice, portable data file in standard exponential notation. If the above did work you should have been able to see the node voltages as a function of supply voltage and see the diodes move into their conductive band one by one. And see the traditional 0.7 volt drop across each diode. However, various diodes behave differently so acs needs to know what sort of diode you are using. That is what the ``.model'' command line is doing for you -- it associated parameters in the diode model with a name that you choose to assign to your diodes. (By the way, I have no idea what the true measured parameters are for a real 1N414). >>> Multiplying Two Voltages Using Diode Nonlinearity The above example shows diode voltage drop behaviour but the diode can also be used as an exponential function. In this example, a group of diodes are used to construct a voltage multiplier. Most circuit components add and subtract voltages and currents but multiplication is a bit special. What is done in this circuit is to use the exponential behaviour of the diodes to take the logarithm of two input voltages, then add those up and use another diode to find the exponential of the sum. This works in the same way as a slide rule does. --------------------------------------------------------------------- eg7.ckt MULTILPLY TWO NUMBERS .subckt multiplier 1 2 3 * 1 = input A (voltage) * 2 = input B (voltage) * 3 = output (voltage) * Note that there are scaling factors on inputs and output to keep * diodes in the exponential region. .model dexp D EG=0 CJ=0 FC=0 gparallel=0 G1 0 4 1 0 1e-3 D1 4 0 dexp G2 0 5 2 0 1e-3 D2 5 0 dexp I3 0 6 1 D3 6 0 dexp E1 7 0 4 0 1 E2 8 7 5 0 1 E3 8 9 6 0 1 V1 9 10 0 D4 10 0 dexp H1 3 0 V1 1e6 .ends V1 1 0 0 V2 2 0 0.5 X1 1 2 3 multiplier R1 3 0 1 .options vmin=-1e5 vmax=1e5 .print dc V(3) V(2) V(E1.X1) V(E2.X1) V(E3.X1) .!rm eg7_1.dat eg7_2.dat eg7_3.dat .dc v1 0 1 0.01 > eg7_1.dat QUIET .modify V2=100 .dc v1 0 1 0.01 > eg7_2.dat QUIET .dc v1 0 1000 1 > eg7_3.dat QUIET .end --------------------------------------------------------------------- This example does not attempt to go beyond the multiplication of two numbers, using the DC sweep to test a few ranges of the inputs. The output files can be plotted to check the linearity of the outputs. If you wanted to build a real circuit to perform analog multiplication, you would need something a lot more complex than the above example because the dependent voltage and current sources used in this example would not be possible to construct in a real circuit. Even with those ideal simulator components available, this example will still only multiply correctly within a limited range. Using it outside that range requires adjustment of the input and output scaling factors so that the diodes themselves stay close to exponential functions. This example introduces the concept of a subcircuit which is like a macro facility for circuit simulation. The subcircuit is contained between the ``.subckt'' and ``.ends'' lines and nodes within the subcircuit can use their own numbering, independent of the outside world. The subcircuit gets a name (in this case ``multiplier'') and the component ``X1'' becomes an instance of that subcircuit. Note the way that probes can be put on devices inside the subcircuit, for example ``E1.X1'' refers to the sub-component named ``E1'' inside the subcircuit ``X1''. Another new command here is ``.modify''. In this example, we want to test the multiplier on a few DC sweeps but want to change the value of ``V2'' between the sweeps. This allows a single batch run to test multiple possibilities, or it can also be used interactively to trim a component value into the value that gives the desired operating point. >>> A Matter of Time -- AC Analysis So far the only type of analysis that has been studied has been steady state direct current (or DC). Although a lot can be done with this, it doesn't give you the full picture when your circuit contains capacitors and inductors. These are important devices because they can store energy and because they determine what the time constants of the circuit will be. Time constants have no meaning in steady state DC analysis but the effect of the time constant can be seen by using AC analysis. This allows us to study filter circuits. This example looks at a simple passive filter that is driven by a single voltage source and that contains resistors, capacitors and inductors. This concept could be extended to active filters by using the dependent sources described above or by building op-amp models but for the sake of simplicity passive components are used here. eg8 -- passive 2-port network, use AC sweep to generate bode plot and explain break-points, etc. Explain log plots and why bode is plotted on log-log paper. Explain decibel scale (briefly). Very brief explanation of feedback stability. eg9 -- [explain AC analysis here with some bode plots and pole-zero stuff, can acs do root-locus?] two examples here eg8.ckt, eg9.ckt AC Analysis has the limitation that it is a LINEAR analysis only. This means that the nonlinear devices (such as diodes) must be regarded as behaving like linear devices. In order to achieve this, acs finds the DC operating point first and then presumes that the AC signal is some small value that will slightly perturb the DC operating point but will not be large enough for any nonlinear effect to be visible. Note that circuits that depend on their nonlinearity to extract some feature from the input signal (especially circuits containing diodes) will not behave the same under AC analysis as they might on the test bench. >>> Using the Generator in Transient Analysis At last, we are ready to look at some time domain analysis. Time domain means as it happens in time and is also called ``transient analysis''. The outputs should be the same as you would see looking into an oscilloscope if you were testing a real circuit. This is a simple circuit showing how to calculate a real result for a simple real life problem. The problem is to magnetise some permanent magnets using an electromagnetic coil. Ignoring the physical side of the setup and considering only the electronics, we have an coil which consists of a resistor in series with an inductor, this is being driven by a sinusoidal supply but the supply is only switched on for half a cycle. Here in Australia, the mains supply is 240V RMS AC at 50Hz. Thus, one half cycle lasts for 10 miliseconds. The ``generator'' device provided by acs is the ideal thing to create a pulse such as this. --------------------------------------------------------------------- eg10.ckt MAINS PULSE HITS MAGNETISING RIG V1 1 0 generator 1 R1 0 2 850m L1 1 2 6mH .options vmin=-1e5 vmax=1e5 .generator freq=50 width=10m ampl=339.4 .print tran I(L1) V(1) .op .tran 1e-4 30e-3 >eg10.dat .end ---------------------------------------------------------------------- This can be run in batch mode and the output will be in plottable format in the file ``eg10.dat''. Looking at the plot, it is easy to see the peak current of around 250 Amps (needless to say, don't try the practical experiment at home unless you can handle such surges). Also note the shape of the current pulse is a little bit like an exponential decay and a little bit like a sine wave. You might notice a number of new commands in the above example. Firstly, the word ``generator'' appears in two places. The output end of the generator appears in the specification of V1. When used like this, the generator function is being invoked and the only parameter this function has is a scaling factor (in this case 1 for simplicity). Later n the generator command is invoked on a command line (i.e. begins with dot) and this has a bunch of parameters (three of which are used in this example). It is important not to get confused between the generator function and the generator command, the name is the same but the syntax is different and they are used in different places. As well as the generator, some options are being changed. These options are the maximum and minimum voltages that act as limits for convergence purposes. The default values are suitable for typical amplifier circuits but if you want to work with higher voltages (such as power circuits) then you must explicitly tell the simulator by adjusting these options. You can try the above circuit with lower values for these or with the default values and see that it does alter the output calculation. Currently, there is no warning system to tell you something is wrong so make sure you set them comfortably higher than any voltage you expect to encounter in the circuit. Now there is the transient analysis itself. This analysis works by taking time steps and you must specify how small you want these steps to be and how long the analysis should run for. The output redirection option is the same as for other analyses. One special point about the transient analysis is that you must run an ``op'' analysis first in order to establish the initial conditions. In the example it really is not very important but in other cases it can make a significant difference to transient behaviour. --------------------------------------------------------------------- eg11.ckt CAPACITOR PULSE FOR MAGNETISING RIG .model switch SW VT=150 VH=150 RON=0.1 ROFF=1Meg .model diode D V1 1 0 340 R1 1 2 500 C1 2 0 2000u IC=299.8 S1 2 3 2 0 switch OFF R2 3 4 850m L1 4 0 6mH IC=0 D1 5 3 diode R3 5 0 5 C2 5 0 200u .options vmin=-1e5 vmax=1e5 .print tran I(L1) V(2) V(3) V(5) .tran 0 20e-3 1e-6 >eg11.dat UIC QUIET .end ---------------------------------------------------------------------- This example shows another approach to generating a magnetising pulse -- discharge a capacitor into the coil, depending on the capacitor as a high current source. This also uses some new components and different techniques. Firstly, the coil is still modeled using an inductor in series with a resistor (in this case L1 and R2). The main energy storage capacitor (C1) is fed from a 340V DC source through resistor R1, the value of R1 is such that C1 slowly charges. Since the full charge cycle of C1 is boring, we just tell the simulator that C1 is almost fully charged. To achieve this the option, ``IC=299.8'' is used which implies that the initial condition of C1 is to be charged up to 299.8 volts. Similarly, L1 is also given an initial contition, ``IC=0'', which is to say that at time 0 there is no current flowing in the inductor. Thanks to these initial condition specifications, we don't need to run an ``.op'' operating point analysis prior to the transient analysis. We do, however, need to specify ``UIC'' on the transient analysis command where UIC means ``Use Initial Conditions''. The result is that the simulation shows only the last bit of the slow charge through R1 until the capacitor reaches 300 volts and the switch activates. There are a few more special things about this circuit. Consider the component S1 that connects the capacitor to the coil. This component is a voltage controlled switch. The parameters for the switch are given in the .model command, defining a model called (rather unimaginatively) ``switch''. This defines what the ``ON'' resistance of the switch is and what the ``OFF'' resistance is as well as the thresholds for changing state ON to OFF and OFF to ON. Many devices such as MOSFETs, relays and optocouplers can be approximated by a switch -- admittedly it is an idealised representation, but that may be desirable in some situations and at least acceptable in others. Note that the switch too is given an initial condition (OFF). Run the simulation in batch mode as follows: acs eg19.ckt gnuplot set data style lines plot 'eg11.dat', 'eg11.dat' using 1:3, 'eg11.dat' using 1:4 replot 'eg11.dat' using 1:5 exit Since this run produces rather a lot of output, the ``Quiet'' option is added to the transient analysis in order to avoid excessive scrolling. It should be evident that the voltage in C1 slowly charges up to 300 volts while the switch stays open and nothing much else happens. Then the switch shuts and the C1 voltage starts to fall while the current in L1 rises and the energy is transfered from the capacitor to the inductor. With a resistance of 100 miliohms in the switch and another 850 miliohms in the coil, some of the energy is lost to heat and the inductor reaches peak current (approx 120A) before the capacitor is fully discharged -- ideally the switch could be opened there but in this case the switch is programed to open when the capacitor voltage reaches zero. Finally the capacitor voltage does reach zero and the switch opens. This leaves a noticable kink in the plot of the inductor current and it starts the inductor energy transfering into C2 and R3 through D1. Finally all the energy is dumped into R3 as heat. An interesting thing happens when the inductor current reaches zero and D1 goes back into reverse bias -- the voltage at node 3 goes into a brief high frequency oscillation. Is the simulator playing up here? What is going on? Actually, this is correct behaviour as the last tiny burst of energy in L1 has nowhere to go, it sets up an oscillation between the junction capacitance in D1 and the inductance of L1. This is a property of using diodes to switch a coil and does occur in real circuits too. The simulator does not know the junction capacitance of D1 because it has not been specified in the ``.model'' line (actually with no junction capacitance specified, acs drops the capacitor out of the diode model completely) so the oscillation flips back and forth with each time step and the magnitude of the swing at node 3 is dependent on the size of the timestep used (try a longer timestep and see that node 3 shows a larger voltage swing at this point). In this case, the inductor current is the result of interest but if it were necessary to know exactly how node 3 behaved at the end of the pulse then more care would be required in determining the capacitance at work around node 3 (in particular the diode and switch behaviour). doc/gnucap-ibis.1000066400000000000000000000043321145401216200141040ustar00rootroot00000000000000.\" Hey, Emacs! This is an -*- nroff -*- source file. .TH GNUCAP-IBIS 1 "November 2001" "Debian Project" "Debian GNU" .SH NAME gnucap-ibis \- GNU Circuit Analysis Package IBIS translator .SH SYNOPSIS .B gnucap-ibis [\fB--typ\fP] [\fB--min\fP] [\fB--max\fP] [\fB--power-on\fP] [\fB--on\fP] [\fB--off\fP] filename [\fB--dump\fP [filename]] [\fB--spice\fP [filename]] .br .SH DESCRIPTION .I GNUCAP-IBIS is a IBIS translator tool in the GNUCAP suite. It will transform IBIS models into SPICE models for use in SPICE simulations. .PP The IBIS model in \fIfilename\fP is being parsed and can be translated to whatever format is requested. By using the \fB--spice\fP option a SPICE model can be generated. By using the \fB--dump\fP option a IBIS dump may be performed (mainly for testing purposes). A typical usage can be gnucap-ibis mymodel.ibis -spice .SH OPTIONS .TP \fI--typ\fI sets simulation mode to typical values (default) .TP \fI--min\fI sets simulation mode to minimal values .TP \fI--max\fI sets simulation mode to maximal values .TP \fI--power-on\fI sets device state to power on .TP \fI--on\fI sets device state to on .TP \fI--off\fI sets device state to off .TP \fI--prefix prefix\fI sets the prefix on generated code (default no prefix) .TP \fI--dump [filename]\fI enable the dumping of the interprented IBIS file in IBIS format. Optionally an output filename may be given (default filename is incomming filename with .dump postfix) .TP \fI--spice [filename]\fI enable the dumping of a SPICE model. Optionally an output filename may be given (default filename is incomming filename . mode .ckt). .SH BUGS See .B /usr/share/doc/gnucap/bugs for a list of known bugs in this release. .PP GNUCAP is an ongoing research project. It is being released in a preliminary phase in hopes that it will be useful and that others will use it as a thrust or base for their research. I also hope for some comments that may help me direct my research. .SH AUTHOR GNUCAP is being written by Albert Davis .PP This manual page was written by Magnus Danielson and maintained by Hamish Moffatt for the Debian package of gnucap. For the full LaTeX documentation, please see .B /usr/share/doc/gnucap/manual. doc/gnucap.1000066400000000000000000000057071145401216200131670ustar00rootroot00000000000000.\" Hey, Emacs! This is an -*- nroff -*- source file. .TH GNUCAP 1 "November 2001" "Debian Project" "Debian GNU" .SH NAME gnucap \- GNU Circuit Analysis Package .SH SYNOPSIS .B gnucap [\fB-b\fP filename] [\fB-i\fP filename] .br .SH DESCRIPTION .I GNUCAP is a general purpose circuit simulator. It performs nonlinear dc and transient analyses, fourier analysis, and ac analysis linearized at an operating point. It is fully interactive and command driven. It can also be run in batch mode or as a server. The output is produced as it simulates. Spice compatible models for the MOSFET (level 1,2,3) and diode are included in this release. .PP Since it is fully interactive, it is possible to make changes and re-simulate quickly. The interactive design makes it well suited to the typical iterative design process used it optimizing a circuit design. It is also well suited to undergraduate teaching where Spice in batch mode can be quite intimidating. This version, while still officially in beta test, should be stable enough for basic undergraduate teaching and courses in MOS design, but not for bipolar design. .PP In batch mode it is mostly Spice compatible, so it is often possible to use the same file for both GNUCAP and Spice. .PP The analog simulation is based on traditional nodal analysis with iteration by Newton's method and LU decomposition. An event queue and incremental matrix update speed up the solution for large circuits (at some expense for small circuits). .PP It also has digital devices for mixed signal simulation. The digital devices may be implemented as either analog subcircuits or as true digital models. The simulator will automatically determine which to use. Networks of digital devices are simulated as digital, with no conversions to analog between gates. This results in digital circuits being simulated faster than on a typical analog simulator, even with behavioral models. The digital mode is experimental and needs work. There will be substantial improvements in future releases. .SH OPTIONS Two command-line options are available. Only one of these may be specified. If no parameters are given, gnucap will start in interactive mode. .TP \fI-b filename\fP execute the commands in the named file then exit (batch mode) .TP \fI-i filename\fI execute the commands in the named file then go into interactive mode .SH BUGS See .B /usr/share/doc/gnucap/bugs for a list of known bugs in this release. .PP GNUCAP is an ongoing research project. It is being released in a preliminary phase in hopes that it will be useful and that others will use it as a thrust or base for their research. I also hope for some comments that may help me direct my research. .SH AUTHOR GNUCAP is being written by Albert Davis .PP This manual page was written by Jon Rabone and maintained by Hamish Moffatt for the Debian package of gnucap. For the full LaTeX documentation, please see .B /usr/share/doc/gnucap/manual. doc/history000066400000000000000000001122501145401216200132440ustar00rootroot00000000000000Gnucap revision history ------------------------------------------------------------------ ------------------------------------------------------------------ Gnucap 0.34 release notes (02/01/2004) This is a bug fix and compatibility release. 1. Fix bug causing incorrect interpolation of backwards tables. 2. Fix tanh overflow bug. 3. Fix some parsing bugs. 4. Fix occasional "double load" bug. 5. Fix AC sweep with one point. 6. Transient start time really works. 7. Fix occasional assert fail after option short is changed. 8. Fix memory leak resulting from failure to delete unused common. 9. Fix a Z probe bug that sometimes gave wrong answers. 10. Fix a limiting bug that sometimes caused non-convergence. 11. Configure handles isnan. 12. Improvements to logic initialization. It is still not correct. ------------------------------------------------------------------ Gnucap 0.33 release notes (01/12/2003) This is a bug fix and compatibility release. 0.32 was not widely distributed due to password problems and a heavy work load, so the release notes are repeated after the current ones. New features: 1. Add inductance probes, like capacitor. Bug fixes: 1. Fix xprobe duplicate default arg bug - shows in g++3.2. 2. Fix bug that sometimes caused a crash when changing a model after analysis. 3. Fix bug that caused an assert to fail (debug build) after removing a probe from an element. 4. Fix a dumb typo hack bug ddHAS_READLINE. Now history and command line editing really works. It was working, but somehow the hack slipped into the release code. ------------------------------------------------------------------ Gnucap 0.32 release notes (09/30/2002) New features: 1. Series resistance in the diode. It took 5 minutes to do, so it is embarrasing that it wasn't done before. 2. History and command line editing, using Gnu Readline. Thanks to Simon Hoffe for sending me the patch. 3. More parameters in the BJT model. This gives it better compatibility with commercial simulators. These parameters are beyond Spice 3f5. 4. "M" parameter in diode, BJT and MOS devices. M is the number of parallel devices. Some commercial simulators have this. Changes that may or may not be improvements. 1. The definition of the transient option "UIC" has changed. It is now Spice compatible, which means to not attempt to do any solution or consistency check. Just apply the values, assuming anything that isn't specified is 0. The old behavior was to attempt a solution while holding the IC values. Bug fixes: 1. voltage sync bug. It still doesn't fix the MOS 2 convergence problem. 2. Fix memory leak in POLY components. 3. Fix bug in Fourier that sometimes causes overrun (crash) and time sync errors. 4. Modelgen: fix bug in list parsing. 5. Some changes to eliminate warnings when compiling with g++ 3.1. 6. Use Euler differentiation on first step, because trap used a value that cannot be known then. Usually, this doesn't make much difference, but there are a few cases where the error can get magnified and trigger trapezoidal ringing, leading to a totally bogus result. It most cases, you could hide it with small enough steps. These cases should work with default settings now. 7. Fix bug that sometimes caused incorrect handling of initial conditions (UIC), 8. Fix bug that caused continuing a transient analysis to give incorrect results. Significant internal changes: 1. The inductor uses all of the same support functions as the capacitor, including "integrate", which is now correctly called "differentiate". 2. Most of the code is in place for named nodes. It mostly works and can be turned on with the option "namednodes". It is off by default because it is not complete. Most likely, it will be finished in the next release. Some things that are still partially implemented: 1. BSIM models, charge effects, "alpha0" parameter. (computed then ignored) 2. Configure still doesn't handle everything. 3. The model compiler still requires too much raw coding. 4. Named nodes. If you set the option "namednodes", it will support named nodes, but some things don't work, so it is off by default. 5. The preliminary IBIS code is now included. For now, it is a standalone executable, that reads an IBIS file and generates a netlist. The netlist requires some editing to use, and is not fully compatible anyway. It is included in hopes of recruiting help in finishing the project. Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. 2. An occasional bogus calculation in MOSFETS occurs when a device is reversed. This sometimes causes nonconvergence. 3. The "modify" command with multiple arguments seems to take only the first one. It used to work, but is broken in this release. I am not sure when it broke. ------------------------------------------------------------------ Gnucap 0.31 release notes (03/25/2002) The most significant changes are the BJT model and "binning". New features: 1. BJT model. 2. "Binning" for all MOS models. 3. Internal element: non-quasi-static poly-capacitor. (needed by BJT). 4. Enhancements to the data structures and model compiler to support binning in general. 5. A line prefixed by "*>" is not ignored, in spite of the fact that "*" usually begins a comment. This is a deliberate incompatibility with Spice. If you prefix a line by "*>" it will be interpreted as a non-comment in Gnucap, but a comment in Spice. 6. Circuit line prefixes of ">" and command prefixes of "-->" are ignored. This is so you can copy and paste whole lines, without having to manually remove the prompt string. Changes that may or may not be improvements. 1. It is not the default to include stray resistance in device models. The option "norstray" will revert to the old behavior. This is only a change to the default value of "rstray". Significant internal changes: 1. The internal element non-quasi-static poly-capacitor actually works. It is used by the BJT model, and will eventually be used by MOSFET models. 2. There are now two poly_g devices: "CPOLY_G" and "FPOLY_G". There are interface differences that impact modeling. Previously, there was only one, which is equivalent to the "FPOLY_G". Some things that are still partially implemented: 1. BSIM models, charge effects, "alpha0" parameter. (computed then ignored) 2. Configure still doesn't handle everything. 3. The model compiler still requires too much raw coding. General comments: The new BJT model seems to pass the CircuitSim90 test cases as well as anything else, except where a missing feature prevented it from working. A few files would not run because of named nodes. One file (ring11) failed completely. This file also has MOSFETs, with level 2 models. The MOS level 2 model is not as robust as the BJT. I believe the problem is due to the voltage sync bug that still impacts the MOS model. Most of the models have has a reasonable amount of testing in DC, but inadequate testing in AC and transient. The BJT model has had more testing than the others in AC and transient. All differences (relative to other simulators) that were observed can be attributed to differences in transient step size control or tolerance checking. Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. ------------------------------------------------------------------ GNUCAP 0.30 release notes (10/29/2001) The primary effort has been to finish the model compiler, to the point where it can handle most modeling issues. The second change is to re-release as "gnucap", and add some configuration features to be more consistent with other GNU software. New features: 1. More complete model compiler. 2. "./configure" makes compiling more like other GNU software. Some things that are still partially implemented: 1. Internal element: non-quasi-static poly-capacitor. 2. BSIM models, charge effects, "alpha0" parameter. (computed then ignored) 3. Configure still doesn't handle everything. 4. The model compiler still requires too much raw coding. Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. ------------------------------------------------------------------ ACS 0.29 release notes (06/30/2001) The primary effort has been to implement IBIS, which is still not done. The changes here are mostly infrastructure changes needed to support IBIS. New features: 1. "Fit" function has choice of fit order and extrapolation. You can have order 0, 1, 2, or 3. 2. "Posy" has even and odd options, to determine what happens in the negative region. 3. Modelgen improvements. It now is useful for the whole device, sometimes. It now handles probes and the device side of the model. The diode uses it completely. There are still a few missing features needed for the MOSFET and BJT. 4. Spice-3 compatible semiconductor resistor and capacitor. 5. "Table" model statement. Improvements, bug fixes, etc. 1. Option "numdgt" really works. 2. Better error messages from modelgen. 3. Code changes for optimization of commons. This should reduce memory use, sometimes, by sharing commons. Common sharing is still not fully implemented. 4. Fix two bugs that sometimes caused problems after a "modify" or on a "fault". 5. Better handling of "vmin" and "vmax". It should be much less likely that limiting causes convergence to a nonsense result. Some things that are still partially implemented: 1. Internal element: non-quasi-static poly-capacitor. 2. BSIM models, charge effects, "alpha0" parameter. (computed then ignored) Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. 2. The makefile does not set up the proper link for the model compiler. You need to do it manually. 3. On some systems, you will get a warning from the linker that "the use of 'tmpnam' is dangerous". You can ignore this warning. ------------------------------------------------------------------ ACS 0.28 release notes (09/05/2000) New features: 1. New probes: diode G, mos IBD, IBS, GBD, GBS. 2. New options: "floor" and "vfloor". (Floor was in the manual, but not in the simulator.) Improvements, bug fixes, etc. 1. There is a change to the way behavioral modeling conditionals are handled. It should now be 100% compatible with SPICE, considering the subset that duplicates SPICE. There are still significant extensions beyond SPICE, particularly that you can have behavioral resistors, capacitors, inductors, etc. 2. Parameter default calculations are now done in a manner consistent with Spice 3f5. Previously, it was supposedly consistent with Spice 2g6. 3. A bug in calculation of threshold voltage of the level 6 model, for P channel devices, has been fixed. 4. A bug in calculation of Meyer capacitances when the device is reversed has been fixed. This bug sometimes caused a discontinuity at vds=0. 5. I have added some smoothing to the Meyer mos capacitor models. This improves convergence. The down side is that sometimes the answers are different. It is probably a little better, when considering closeness to reality, but it is still Meyer's model. 6. MOSFET parasitic diodes are now the same as those used in Spice. 7. There are subtle changes in the diode model. I think this usually improves convergence. 8. Charge calculation in Meyer capacitors and diode capacitiors is now supposedly Spice 3 compatible. 9. An error in BSIM3 scaling has been fixed. Some things that are still partially implemented: 1. Internal element: non-quasi-static poly-capacitor. 2. BSIM models, charge effects. Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. 2. The makefile does not set up the proper link for the model compiler. You need to do it manually. 3. A bad setting of "vmax" and "vmin" can lead to convergence to a nonsense result. It is not as bad now as it used to be. ------------------------------------------------------------------ ACS 0.27 release notes (06/03/2000) New features: 1. BSIM3 model, DC. They work for AC and transient analysis, but only the DC effects actually work. The next release should have the charge effects. For now, it fakes it with Meyer's model. 2. A first cut at a model compiler, to aid in development of new models. Models are described in a ".model" file, which is processed to automatically generate the ".h" and ".cc" files. This version fully handles the ".model" statement part of it, but leaves the device and common sections the old way. Eventually, the entire process will be automated. The old way still works. 3. "Fit" behavioral modeling function, which fits a curve to a set of data. You can specify the order of the fit, which is piecewise polynomials. For now, the order may be 1 (linear, like PWL) or 3 (cubic splines). You may also specify the boundary consitions. 4. More probes. Some things that are partially implemented: 1. Internal element: non-quasi-static poly-capacitor. It is needed by the BSIM3 and EKV models. Eventually, it will be available as a netlist item, but not yet. Bug fixes: 1. PWL could fail if there were duplicate points at the beginning. It still does, but gives a reasonable error message. 2. Some "dot commands" were ignored if there were spaces before the dot. This was particularly annoying if the line was supposed to be ".end" which should make it exit. It didn't, leaving it in interactive mode, a major annoyance in a script. Other improvements: 1. There is a change to the way integration in capacitors is done. It is now strictly based on charge (i = dq/dt). The old version was based on capacitance (i = C * dv/dt) which is strictly incorrect. The dC/dt term was missing (i = C * dv/dt + v * dC/dt). This is a non-issue when C is constant. 2. More documentation on internals. Changes that I think are improvements, but some may disagree: 1. The command line is a little different. In the old version, "acs file" would run it, and whether it exited or not depended on whether there was an ".end" line. Now, by default, it just loads the file in preparation for interactive use. If you want batch mode, say "acs -b file". 2. The regression suite is included in the standard distribution. Changes that are not really improvements: 1. Due to the model compiler, the build process is a little more complicated. To do a complete build, you must build the model compiler first, then the simulator. If you are not making any new models, you can probably get away with just building the simulator. This will change in a future release. Bugs: 1. The transmission line initial conditions are not propagated until the transient analysis runs. 2. The makefile does not set up the proper link for the model compiler. You need to do it manually. ------------------------------------------------------------------ ACS 0.26 release notes (02/02/2000) New features: 1. BSIM1, BSIM2 models -- DC only. They work for AC and transient analysis, but only the DC effects actually work. The next release should have the charge effects. 2. New elements: trans-capacitor voltage controlled capacitor voltage controlled conductance voltage controlled resistor This is a side effect of the BSIM work. 3. Optional new syntax, with type first so component labels can start with any letter, and the choice of components is no longer limited by the 26 letters. This was necessary for a clean syntax for #2. 4. Some new parameters on existing devices, also a side effect of the BSIM work. 5. The manual in HTML form. The manual source is still in LaTeX, which can be used to generate HTML, PDF, Postscript, or many other formats. Bug fixes: 1. An error causing truncation error to be underestimated has been fixed. Other improvements: 1. MOSFET model evaluation is a little faster, due to use of one of the new elements to replace several old ones. I have seen 40%, but 20% is more likely. The improvement is most evident on busy circuits, where the ACS speed enhancements based on latency exploitation contribute more overhead than their value, that is .. the type of circuit that has run faster in Spice than ACS. 2. More documentation on internals. Changes that I think are improvements, but some may disagree: 1. Truncation error based step control is disabled when Euler's method is selected. The justification for this is that the reason for selecting Euler's method is to avoid the artifacts of high order methods on "stiff" poles. Without this change, a "stiff" pole would cause an unreasonably small step size. This did not appear to be much of a problem in the old release because the use of an incorrect formula for estimating truncation error. A "stiff" pole is one that has a response so fast it can be thought of as instantaneous. 2. The "help" command, with its 4 year old help file, has been removed. The concept is really obsolete. With the HTML form of the manual, a full online manual is a better replacement. ------------------------------------------------------------------ ACS 0.25 release notes (11/04/99) New features: None! Bug fixes: 1. A name conflict that caused compile to fail with gcc 2.95 has been fixed. 2. A problem that caused switches to lose state when a simulation is stopped and restarted when a switch is in transition has been fixed. 3. Two unrelated problems with transmission lines have been fixed. (Short lines and lines in subcircuits.) Changes that may or may not be improvements: 1. Several queues have been added, to manage model evaluation scheduling. This is part of work on multi-rate and mixed-mode simulation, and it replaces the traditional bypass scheme. In this release, probably the only noticeable difference will be that it runs a little faster. Known bugs: 1. The help file has not been updated for 4 years. ------------------------------------------------------------------ ACS 0.24 release notes (08/21/99) New features: 1. Enhanced (now documented) behavioral modeling. 2. Transmission line in transient analysis. 3. More documentation of internals. 4. Better batch mode error handling. Bug fixes: 1. Control-C trap works. 2. A bug that could cause a crash when a device had an improper number of nodes has been fixed. It now issues a warning, and grounds the unspecified nodes. 3. A bug that could cause a crash when a model or subcircuit is deleted then accessed has been fixed. 4. A scoping bug that sometimes put subckt parts in the root circuit has been fixed. 5. A bug in "fanout" that listed internal subckt nodes incorrectly has been fixed. Changes that may or may not be improvements: 1. "Make2" files for some systems have been removed. These have not been tested in years, and ACS and the compilers have both evolved significantly, so any portability patches that old are probably completely wrong now. Known bugs: 1. The help file has not been updated for 4 years. ------------------------------------------------------------------ ACS 0.23 release notes (06/15/99) New features: 1. Level 6 mos model. 2. HSpice style PWL and POLY(1). 3. "Table" behavioral modeling function. 4. Mixed-mode digital initialization. The bug fixes: 1. The alarm range worked backwards, now fixed. 2. Keep track of commons better. 3. Improved mixed-mode simulation. It still has not been tested as well as I would like, but is better. Digital initialization works now. 4. Another case of "zero time step" has been fixed. This one was relatively benign, in that it only caused a single extra full evaluation, with immediate recovery to a normal step size. 5. "Z" probe gave wrong results when probing a voltage source. Other improvements: (?) 1. Some subtractions now de-noise the result, eliminating the tiny numbers that result from subtracting two nearly equal numbers. The threshold can be set by the option "roundofftol". It is best left set at 1e-13. This improves speed slightly because 0 will prevent a matrix reload, but any non-zero number will not. It improves convergence slightly because the tiny numbers (which result from numerical problems) tend to cause further numerical problems. These tiny numbers are an artifact of the machine math, and vary depending on optimization and machine implementation details. 2. MOS temperature effects are computed at run time, instead of at load time, so you can change the temperature after loading and get correct results. 3. The options for integration method have changed, and are more flexible. The default is still trapezoidal, but that may change in a future release. You can specify the mode individually for capacitors and inductors. The information is in the data structure for all components, but it isn't always parsed. A future release will let you specify it by component or by model. The names are Spectre compatible, not Spice compatible, because it is more flexible. The Spice names are accepted, but may not act the same as they do in Spice. Choices are: unknown, euler, euleronly, trap, traponly. Options accepted and coerced into something else are: gear2, gear2only, trapgear, trapeuler. In general, gear is treated as euler, and each element will use either euler or trap. The device choice wins over the option command choice, but "only" wins over non-only. 4. Logic device syntax is changed. There are two more nodes, so power, ground, and enable are passed in. Power and enable are not used (except possibly in subckt models) but are required for consistency. 5. In many (not all) cases, arbitrary limits, due to fixed size arrays, have been removed. 6. More rigorous testing. I actually have a regression suite now. It is still not rigorous enough. 7. More rigorous convergence criteria. This should solve some of the false convergence problems. ACS convergence criteria has always been more rigorous than Spice. The cosmetic changes: 1. Convert most containers to STL. 2. Complete migration to the "common" tree, and eliminating reference to the old C "x" structure extensions. 3. Rearrangement of MOS model hierarchy, to make it easier to install other models. (BSIM family is coming.) ------------------------------------------------------------------ ACS 0.22 release notes (10/16/98) This release contains a few bug fixes, and a few cosmetic changes to the code. The bug fixes: 1. Fixes convergence failures in circuits with linear inductors, linear mutual inductors, and linear current controlled sources. 2. Fixes a bypass problem, which shows as transient analysis failure with the message "very backward time step". 3. Failed assertion on switch. The cosmetic changes: 1. The "OMSTREAM" class, as a step in migrating the i/o to C++ style. 2. A cleaner event queue, using a generic heap class. That's really all. I have not been actively working on ACS, mostly due to employment at a semiconductor company in their "corporate CAD" department. This will change soon, because my new employer (a CAD tool vendor) says it is ok to work on ACS. ------------------------------------------------------------------ ACS 0.21 release notes (03/30/96) There are several changes, most of which are only visible in subtle ways from the outside. 1. The code is more conformant with the upcoming standard, particularly in the use of complex, templates, lifetime of temporaries, and for scope. This should fix problems compiling with g++ 2.7. 2. Element commons are freed properly. 3. The manner in which elements are loaded into the matrix is different, and should be faster for large circuits with latency. Model bypass is more complete, because it is no longer necessary to do anything with a latent model. It makes little difference for small circuits, and circuits that are mostly active. Speed gains on small circuits are offset by #4. 4. The bypass criteria are more strict. It was possible to get incorrect results through interaction between model evaluation bypass and iteration damping. This release will not bypass anything when damping is in effect. There is a slight speed penalty. 5. Logic devices work even when there is no analog model. The bug causing a failure in this case has been fixed. The "bug" (that could in a twisted sense be called a feature) that leads to random mapping on start-up is still there. The logic model still needs work. 6. The code is somewhat more object-oriented. Some classes have been changed to be more general. ------------------------------------------------------------------ ACS 0.20 release notes (11/22/95) This release adds the level-3 MOSFET model. It is Spice compatible. Actually, it was there a long time ago but was removed because it didn't work correctly. This one has been tested and seems to match Spice results, and have convergence characteristics a little better than Spice 2g6. Like the level 1 and 2 models, only Meyer's capacitance model is implemented. (like Spice 3). ------------------------------------------------------------------ ACS 0.19 release notes (10/31/95) This release offers "improved" convergence. Several new options have been added to control iteration damping. In some cases, the program will take a partial step in an attempt to tame the wild fluctuations that can occur during iteration with Newton's method. This version appears to be considerably more robust than Spice 2g6. Several test circuits that fail to converge on Spice do converge on ACS. The cost of this is sometimes slower convergence. It generally takes about 2 more iterations per step than the previous version. This can be turned off, using the "dampstrategy" option at a slight cost in robustness. See the manual on the options command for more information. ------------------------------------------------------------------ ACS 0.18 release notes (05/12/95) This release offers improved memory management and exception handling, primarily aimed at MSDOS systems. Bug fixes: 1. For all ... Out of memory exceptions are properly trapped. Version 0.17 would crash if it ran out of memory. Now you get a reasonable message. It was only a real problem on MSDOS systems. 2. MSDOS floating point exceptions are trapped. In 0.17, underflow exceptions and null floating point exceptions could sometimes cause an abort. I don't know why, but the 80287 can generate a null exception when apparently nothing is wrong. 3. MSDOS only: Evade underflow in exp(). A large negative argument to exp can give bogus results. This was a known (to me) in Microsoft C 5.1. Apparently Borland has the same behavior. It may be a hardware problem. The fix is to not call exp with an argument beyond -200, and return 0 instead. 4. Don't use "-fast-math" with g++. (Makefile change). It doesn't make any difference in speed, and it sometimes causes problems, particularly the one in #3 above. Performance improvements: 1. Most elements no longer store values from the past. Only inductors and capacitors do. This means that some probes are no longer available. Some other data has been moved to improve memory usage. This change increases the capacity of the MSDOS version by about 10 transistors. Unix systems will swap less. Other visible changes: 1. The method of attaching models to devices has been changed, to improve maintainability. There are a few noticeable side effects. a. The default models -d-, -n- are no longer available. These were not documented. b. Model names must now be unique. If you have a diode model named "foo", you may not also have a mosfet model named "foo". c. A diode can reference a mosfet model. The diode will be equivalent to the source-bulk diode in the mosfet. This is a byproduct of using C++ derived classes. The mosfet model is derived from the diode model. 2. Exception handling in batch mode is different. It is still not right. ------------------------------------------------------------------ ACS 0.17 release notes (04/21/95) The primary difference in this release is reorganization and C++. A side benefit is that it is slightly faster, and uses slightly less memory. (The program is bigger, but it stores data more efficiently, for a net improvement.) It is a transitional release, with some of the code still in C. I hope to have a full C++ version this summer. Bug fixes: 1. Voltage source (vs, vcvs, ccvs) probes (current, power, etc.) now really work. 2. Fixed bug that caused strange results with mutual inductance after other parts of the circuit are changed. 3. Fixed memory leak in subcircuits and complex devices. 4. Fixed bug that caused a crash when probed elements were deleted. ------------------------------------------------------------------ ACS 0.16 release notes (12/10/94) New features: 1. New components: current controlled switch, current controlled current source, current controlled voltage source. Any simple two terminal element (not a diode) can be used as a probe, not just a voltage source. 2. Diode transit time parameter works. 3. Mutual inductance. The coupled coils must be linear. Only pairs of coupled inductors are supported in this release. A future release will probably support multiply coupled inductors. Bug fixes: 1. Continuing a transient analysis now works as documented. ------------------------------------------------------------------ ACS 0.15 release notes (07/31/94) Version 0.15 is supposed to be a minimal bug fix release to 0.14, but does have one new component. 1. Some additional ports are supported, including VMS. An HP port is supplied as a user contribution, but I have not tested it. 2. New component: voltage controlled switch. Spice-3 compatible. 3. Fixed bug that caused unpredictable behavior (usually loss of a probe, sometimes a crash) after replacing a component. 4. Fixed bug that caused incorrect evaluation and initialization of logic devices when there is no analog model. 5. Fixed a bug in truncation error control that sometimes caused it to become a no-op. It still seems to usually work the same as Spice, except that ACS will actually use at least the time steps you ask for. Spice will pick all the steps and interpolate for the points you ask for. This will usually cause ACS to use more time steps than Spice, hence often slower simulations. 6. Fixed another bug in truncation error that sometimes caused a divide by zero. ------------------------------------------------------------------ ACS 0.14 release notes (07/05/94) Version 0.14 was supposed to be a minimal bug fix release to 0.13. The same bugs are still there and there are a few small additions mostly aimed at coping with convergence problems. 1. The truncation error formula was changed to use the third derivative of charge instead of the second derivative of current. These two numbers are theoretically equal, but in practice they are not. The second derivative of current uses 3 terms to compute by divided differences. The third derivative of charge uses 4 terms. Using the odd number of terms catches the error due to the oscillatory nature of the trapezoid rule. An even number of terms tends to lose this error. Also, using charge tends to mask it. So, I have changed it to a less accurate, more optimistic method, the same as Spice. It now seems to work about the same as Spice, in the sense that it usually chooses about the same step sizes. Strictly, the old method is "better" but it tends to run away on stiff poles, trying for excess accuracy that doesn't matter. Your comments on this matter are welcome. If you know of any good papers on this, please let me know. 2. The "stiff" option has been removed from the transient command. Instead, use the .options "trapezoid" or "gear". For now, "gear" implies first order and is equivalent to the old "stiff". (A cop-out.) Actually, for stiff poles you want a first order method because the error is lower. 3. You can specify the integration method individually on any capacitor or inductor. 4. A bug causing the MSDOS version (2 byte integers) to mess up probes of other than nodes was fixed. 5. A bug that sometimes caused it to perpetually repeat the same time step was fixed. (SPICE would have reported "time step too small" and stopped.) 6. A bug that messed up step control when a dormant model wakes up and finds out it has been sleeping too long has been fixed. 7. "Mosflags" and "diodeflags" are different and there are more of them. There are lots of them and they may be useful in taming convergence problems. They control the heuristics that are applied when there appears to be a convergence problem. I have yet to find a circuit that could not be made to converge by judicious application of the flags and options, but any one setting is no better than Spice, and many are worse. One combination of flags gives Spice style limiting, which more often than not makes convergence worse. 8. "vmax" and "vmin" options as part of convergence heuristics. The default value of "limit" now large enough to essentially remove it. These limits sometimes help convergence, but more often hurt. 9. The "damp" option actually works. 10. The diode "off" flag works correctly. 11. There is a new command "alarm" that prints a message when a value exceeds a range. The syntax is the same as the "plot" command. ------------------------------------------------------------------ ACS 0.13 release notes (03/11/94) Version 0.13 adds several new features and has several bug fixes and performance improvements. 1. Fourier analysis really works. The "Fourier" command does a transient analysis but prints the results in the frequency domain. It is similar to the Spice command of the same name but not exactly the same. It is significantly more accurate than Spice because the transient time steps are chosen for the best match to the Fast Fourier Transform. Considerably more flexibility is available than in Spice. 2. Transient time step control by truncation error (finally). 3. Several options have been added to display diagnostics. 4. Fixed the default value for idsat, issat, ad, and as in the mos-diode. In 0.12, the default area was 1 square meter, which gave mosfet capacitors in the 500 uf range. This sometimes caused strange results. 5. Added some node probes, mostly for diagnostic use. 6. Fixed the "F" probe on linear elements. (Capacitor charge, inductor flux, admittance current, resistor voltage) It used to give an obviously bogus answer. Other changes: 1. Some general changes in the interest of improving code quality in general. 2. Function headers are in ANSI style, rather than K&R style. This version will compile as either C or C++. Future versions will require a C++ compiler. ------------------------------------------------------------------ ACS 0.12 release notes (10/09/93) Version 0.12 is a maintenance release. It adds no features (except Ultrix support) but fixes several bugs and changes some porting details. It should be easier to port this version than previous versions. The bug fixes are significant enough that you should upgrade to 0.12 even if you are not having any problems. ------------------------------------------------------------------ ACS 0.11 release notes (07/26/93) Version 0.11 fixes a few bugs in 0.10. 0.10 was supposed to be posted on alt.sources but due to a problem with the feed it never happened. New features: 1. New MOSFET and diode probes. All information available from the Spice 2 "op" analysis is now available as probes. For MOSFET these include cbd, cbs, cgsovl, cgdovl, cgbovl, cgs, cgd, cgb, vdsat, vth. Other (non-spice) new probes include cgst, cgdt, cgbt. (cgst = Cgs total = cgsovl + cgs.) These were available before by probing the value of the internal element but it was less convenient. Now it is simple and has the same name as in Spice. These probes are also available in transient analysis, so you can see (for example) the dynamic variations in capacitance. Bugs fixed: 1. Pass arguments to tr_volts and family by pointer instead of the whole structure. This is less likely to tickle a bug in Microsoft C. The MSDOS version of ACS 0.10 crashed frequently due to this bug. (Strictly, this is a Microsoft-C bug, not an ACS bug but the effect is the same.) 2. The AC "Z" probes work again. They were broken in 0.10. 3. The size of the buffer for text plots is increased allowing support for wider screens. The old version would crash if you did plots with outwidth set to wider than 128. The fix is to make it bigger, with a new constant MAXWIDTH, and trap the width setting bigger than MAXWIDTH. The current max is 256 for MSDOS and 512 for unix. The plotting code should probably be redone. 4. Width is narrower by 1 so setting width to 80 won't leave blank lines on an 80 column screen. 5. MOSFET capacitance now matches Spice (Meyer model) 6. Level 1 model linear region gds calculation was wrong, but close enough to often go unnoticed. It is correct and matches Spice now. 7. The value of an AC source now is compatible with Spice. That is, plain value is the DC-tran value. In old versions of ACS a plain value applied to all analyses including AC. You needed to prefix the value with "DC" to make it not apply to AC. Actually, it worked as documented. Now it works like Spice, which makes more sense. This was a major source of strange results in AC analysis. ------------------------------------------------------------------ ------------------------------------------------------------------ doc/relnotes.029000066400000000000000000000051261145401216200137120ustar00rootroot00000000000000ACS 0.29 release notes (06/30/2001) The primary effort has been to implement IBIS, which is still not done. The changes here are mostly infrastructure changes needed to support IBIS. New features: 1. "Fit" function has choice of fit order and extrapolation. You can have order 0, 1, 2, or 3. 2. "Posy" has even and odd options, to determine what happens in the negative region. 3. Modelgen improvements. It now is useful for the whole device, sometimes. It now handles probes and the device side of the model. The diode uses it completely. There are still a few missing features needed for the MOSFET and BJT. 4. Spice-3 compatible semiconductor resistor and capacitor. 5. "Table" model statement. Improvements, bug fixes, etc. 1. Option "numdgt" really works. 2. Better error messages from modelgen. 3. Code changes for optimization of commons. This should reduce memory use, sometimes, by sharing commons. Common sharing is still not fully implemented. 4. Fix two bugs that sometimes caused problems after a "modify" or on a "fault". 5. Better handling of "vmin" and "vmax". It should be much less likely that limiting causes convergence to a nonsense result. Some things that are still partially implemented: 1. Internal element: non-quasi-static poly-capacitor. 2. BSIM models, charge effects, "alpha0" parameter. (computed then ignored) Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. 2. The makefile does not set up the proper link for the model compiler. You need to do it manually. 3. On some systems, you will get a warning from the linker that "the use of 'tmpnam' is dangerous". You can ignore this warning. Hot items for a future release (no promises, but highly probable): 1. Charge effects and substrate current (alpha0) in BSIM models. They are computed, but not loaded to the matrix. 2. Completion of model compiler, and its documentation. 3. Completion of multi-rate. 4. Homotopy methods to improve convergence. 5. Transmission line accuracy and speed improvements, using a step control mechanism similar to that used for capacitors. 6. Parameterized subcircuits and defined parameters. 7. A "trigger" element, so time dependent values can be triggered by the circuit, as an alternate to simple time. 8. IBIS support. 9. Spice-3 compatible "B" device. To reach me, try this email address: aldavis@ieee.org ACS ftp sites: ftp://ftp.geda.seul.org/pub/geda/dist/acs-0.29.tar.gz http://www.geda.seul.org/dist/acs-0.29.tar.gz ftp://sunsite.unc.edu/pub/Linux/apps/circuits/acs-0.29.tar.gz doc/relnotes.030000066400000000000000000000032171145401216200137010ustar00rootroot00000000000000GNUCAP 0.30 release notes (10/29/2001) The primary effort has been to finish the model compiler, to the point where it can handle most modeling issues. The second change is to re-release as "gnucap", and add some configuration features to be more consistent with other GNU software. New features: 1. More complete model compiler. 2. "./configure" makes compiling more like other GNU software. Some things that are still partially implemented: 1. Internal element: non-quasi-static poly-capacitor. 2. BSIM models, charge effects, "alpha0" parameter. (computed then ignored) 3. Configure still doesn't handle everything. 4. The model compiler still requires too much raw coding. Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. Hot items for a future release (no promises, but highly probable): 1. BJT model. The model compiler is complete enough that it should be easy now. 2. Charge effects and substrate current (alpha0) in BSIM models. They are computed, but not loaded to the matrix. 3. Completion of multi-rate. 4. Homotopy methods to improve convergence. 5. Transmission line accuracy and speed improvements, using a step control mechanism similar to that used for capacitors. 6. Parameterized subcircuits and defined parameters. 7. Spice-3 compatible "B" device. To reach me, try this email address: aldavis@ieee.org ftp sites: ftp://ftp.gnu.org/gnu/gnucap/gnucap-0.30.tar.gz ftp://ftp.geda.seul.org/pub/geda/dist/gnucap-0.30.tar.gz http://www.geda.seul.org/dist/gnucap-0.30.tar.gz ftp://sunsite.unc.edu/pub/Linux/apps/circuits/gnucap-0.30.tar.gz doc/relnotes.031000066400000000000000000000105351145401216200137030ustar00rootroot00000000000000Gnucap 0.31 release notes (03/25/2002) The most significant changes are the BJT model and "binning". New features: 1. BJT model. 2. "Binning" for all MOS models. 3. Internal element: non-quasi-static poly-capacitor. (needed by BJT). 4. Enhancements to the data structures and model compiler to support binning in general. 5. A line prefixed by "*>" is not ignored, in spite of the fact that "*" usually begins a comment. This is a deliberate incompatibility with Spice. If you prefix a line by "*>" it will be interpreted as a non-comment in Gnucap, but a comment in Spice. 6. Circuit line prefixes of ">" and command prefixes of "-->" are ignored. This is so you can copy and paste whole lines, without having to manually remove the prompt string. Changes that may or may not be improvements. 1. It is not the default to include stray resistance in device models. The option "norstray" will revert to the old behavior. This is only a change to the default value of "rstray". Significant internal changes: 1. The internal element non-quasi-static poly-capacitor actually works. It is used by the BJT model, and will eventually be used by MOSFET models. 2. There are now two poly_g devices: "CPOLY_G" and "FPOLY_G". There are interface differences that impact modeling. Previously, there was only one, which is equivalent to the "FPOLY_G". Some things that are still partially implemented: 1. BSIM models, charge effects, "alpha0" parameter. (computed then ignored) 2. Configure still doesn't handle everything. 3. The model compiler still requires too much raw coding. General comments: The new BJT model seems to pass the CircuitSim90 test cases as well as anything else, except where a missing feature prevented it from working. A few files would not run because of named nodes. One file (ring11) failed completely. This file also has MOSFETs, with level 2 models. The MOS level 2 model is not as robust as the BJT. I believe the problem is due to the voltage sync bug that still impacts the MOS model. Most of the models have has a reasonable amount of testing in DC, but inadequate testing in AC and transient. The BJT model has had more testing than the others in AC and transient. All differences (relative to other simulators) that were observed can be attributed to differences in transient step size control or tolerance checking. Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. Bugs (newly discovered, not fixed): 1. In some cases, it is possible for the voltages at various stages of model evaluation to get out of sync with each other. In particular, when device limiting occurs, the conversion from FPOLY to CPOLY form may use the unlimited voltages, resulting in an erroneous conversion. This problem has been fixed (before release) in the DC BJT model. The charge portion of the BJT model may still have the problem, but the symptom rarely shows. The MOS model is known to still have the problem. The symptom of the problem is occasional slow convergence or non convergence. There can be a single incorrect iteration that throws the solution far from the intended path, then it usually recovers eventually. The fix is known, but I wanted to get the BJT model out, so this fix will wait for the next release. 2. The "modify" command with multiple arguments seems to take only the first one. It used to work, but is broken in this release. I am not sure when it broke. Hot items for a future release (no promises, but highly probable): 1. Charge effects and substrate current (alpha0) in BSIM models. They are computed, but not loaded to the matrix. It was deferred waiting for the poly-cap, but now that the poly-cap works, this missing part of the MOS models should be working soon. 2. JFET model. 3. Completion of multi-rate. 4. Homotopy methods to improve convergence. 5. Transmission line accuracy and speed improvements, using a step control mechanism similar to that used for capacitors. 6. Parameterized subcircuits and defined parameters. 7. Spice-3 compatible "B" device. To reach me, try this email address: aldavis@ieee.org ftp sites: ftp://ftp.gnu.org/gnu/gnucap/gnucap-0.31.tar.gz ftp://ftp.geda.seul.org/pub/geda/dist/gnucap-0.31.tar.gz http://www.geda.seul.org/dist/gnucap-0.31.tar.gz ftp://sunsite.unc.edu/pub/Linux/apps/circuits/gnucap-0.31.tar.gz doc/relnotes.032000066400000000000000000000100721145401216200137000ustar00rootroot00000000000000Gnucap 0.32 release notes (09/30/2002) New features: 1. Series resistance in the diode. It took 5 minutes to do, so it is embarrasing that it wasn't done before. 2. History and command line editing, using Gnu Readline. Thanks to Simon Hoffe for sending me the patch. 3. More parameters in the BJT model. This gives it better compatibility with commercial simulators. These parameters are beyond Spice 3f5. 4. "M" parameter in diode, BJT and MOS devices. M is the number of parallel devices. Some commercial simulators have this. Changes that may or may not be improvements. 1. The definition of the transient option "UIC" has changed. It is now Spice compatible, which means to not attempt to do any solution or consistency check. Just apply the values, assuming anything that isn't specified is 0. The old behavior was to attempt a solution while holding the IC values. Bug fixes: 1. voltage sync bug. It still doesn't fix the MOS 2 convergence problem. 2. Fix memory leak in POLY components. 3. Fix bug in Fourier that sometimes causes overrun (crash) and time sync errors. 4. Modelgen: fix bug in list parsing. 5. Some changes to eliminate warnings when compiling with g++ 3.1. 6. Use Euler differentiation on first step, because trap used a value that cannot be known then. Usually, this doesn't make much difference, but there are a few cases where the error can get magnified and trigger trapezoidal ringing, leading to a totally bogus result. It most cases, you could hide it with small enough steps. These cases should work with default settings now. 7. Fix bug that sometimes caused incorrect handling of initial conditions (UIC), 8. Fix bug that caused continuing a transient analysis to give incorrect results. Significant internal changes: 1. The inductor uses all of the same support functions as the capacitor, including "integrate", which is now correctly called "differentiate". 2. Most of the code is in place for named nodes. It mostly works and can be turned on with the option "namednodes". It is off by default because it is not complete. Most likely, it will be finished in the next release. Some things that are still partially implemented: 1. BSIM models, charge effects, "alpha0" parameter. (computed then ignored) 2. Configure still doesn't handle everything. 3. The model compiler still requires too much raw coding. 4. Named nodes. If you set the option "namednodes", it will support named nodes, but some things don't work, so it is off by default. 5. The preliminary IBIS code is now included. For now, it is a standalone executable, that reads an IBIS file and generates a netlist. The netlist requires some editing to use, and is not fully compatible anyway. It is included in hopes of recruiting help in finishing the project. Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. 2. An occasional bogus calculation in MOSFETS occurs when a device is reversed. This sometimes causes nonconvergence. 3. The "modify" command with multiple arguments seems to take only the first one. It used to work, but is broken in this release. I am not sure when it broke. Hot items for a future release (no promises, but highly probable): 1. Charge effects and substrate current (alpha0) in BSIM models. They are computed, but not loaded to the matrix. It was deferred waiting for the poly-cap, but now that the poly-cap works, this missing part of the MOS models should be working soon. 2. JFET model. 3. Completion of multi-rate. 4. Homotopy methods to improve convergence. 5. Transmission line accuracy and speed improvements, using a step control mechanism similar to that used for capacitors. 6. Parameterized subcircuits and defined parameters. 7. Spice-3 compatible "B" device. To reach me, try this email address: aldavis@gnu.org ftp sites: ftp://ftp.gnu.org/gnu/gnucap/gnucap-0.32.tar.gz ftp://ftp.geda.seul.org/pub/geda/dist/gnucap-0.32.tar.gz http://www.geda.seul.org/dist/gnucap-0.32.tar.gz ftp://sunsite.unc.edu/pub/Linux/apps/circuits/gnucap-0.32.tar.gz doc/relnotes.033000066400000000000000000000114711145401216200137050ustar00rootroot00000000000000Gnucap 0.33 release notes (01/12/2003) This is a bug fix and compatibility release. 0.32 was not widely distributed due to password problems and a heavy work load, so the release notes are repeated after the current ones. New features: 1. Add inductance probes, like capacitor. Bug fixes: 1. Fix xprobe duplicate default arg bug - shows in g++3.2. 2. Fix bug that sometimes caused a crash when changing a model after analysis. 3. Fix bug that caused an assert to fail (debug build) after removing a probe from an element. 4. Fix a dumb typo hack bug ddHAS_READLINE. Now history and command line editing really works. It was working, but somehow the hack slipped into the release code. ================================================================= Gnucap 0.32 release notes (09/30/2002) New features: 1. Series resistance in the diode. It took 5 minutes to do, so it is embarrasing that it wasn't done before. 2. History and command line editing, using Gnu Readline. Thanks to Simon Hoffe for sending me the patch. 3. More parameters in the BJT model. This gives it better compatibility with commercial simulators. These parameters are beyond Spice 3f5. 4. "M" parameter in diode, BJT and MOS devices. M is the number of parallel devices. Some commercial simulators have this. Changes that may or may not be improvements. 1. The definition of the transient option "UIC" has changed. It is now Spice compatible, which means to not attempt to do any solution or consistency check. Just apply the values, assuming anything that isn't specified is 0. The old behavior was to attempt a solution while holding the IC values. Bug fixes: 1. voltage sync bug. It still doesn't fix the MOS 2 convergence problem. 2. Fix memory leak in POLY components. 3. Fix bug in Fourier that sometimes causes overrun (crash) and time sync errors. 4. Modelgen: fix bug in list parsing. 5. Some changes to eliminate warnings when compiling with g++ 3.1. 6. Use Euler differentiation on first step, because trap used a value that cannot be known then. Usually, this doesn't make much difference, but there are a few cases where the error can get magnified and trigger trapezoidal ringing, leading to a totally bogus result. It most cases, you could hide it with small enough steps. These cases should work with default settings now. 7. Fix bug that sometimes caused incorrect handling of initial conditions (UIC), 8. Fix bug that caused continuing a transient analysis to give incorrect results. Significant internal changes: 1. The inductor uses all of the same support functions as the capacitor, including "integrate", which is now correctly called "differentiate". 2. Most of the code is in place for named nodes. It mostly works and can be turned on with the option "namednodes". It is off by default because it is not complete. Most likely, it will be finished in the next release. Some things that are still partially implemented: 1. BSIM models, charge effects, "alpha0" parameter. (computed then ignored) 2. Configure still doesn't handle everything. 3. The model compiler still requires too much raw coding. 4. Named nodes. If you set the option "namednodes", it will support named nodes, but some things don't work, so it is off by default. 5. The preliminary IBIS code is now included. For now, it is a standalone executable, that reads an IBIS file and generates a netlist. The netlist requires some editing to use, and is not fully compatible anyway. It is included in hopes of recruiting help in finishing the project. Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. 2. An occasional bogus calculation in MOSFETS occurs when a device is reversed. This sometimes causes nonconvergence. 3. The "modify" command with multiple arguments seems to take only the first one. It used to work, but is broken in this release. I am not sure when it broke. Hot items for a future release (no promises, but highly probable): 1. Charge effects and substrate current (alpha0) in BSIM models. They are computed, but not loaded to the matrix. It was deferred waiting for the poly-cap, but now that the poly-cap works, this missing part of the MOS models should be working soon. 2. JFET model. 3. Completion of multi-rate. 4. Homotopy methods to improve convergence. 5. Transmission line accuracy and speed improvements, using a step control mechanism similar to that used for capacitors. 6. Parameterized subcircuits and defined parameters. 7. Spice-3 compatible "B" device. To reach me, try this email address: aldavis@gnu.org ftp sites: ftp://ftp.gnu.org/gnu/gnucap/gnucap-0.32.tar.gz ftp://ftp.geda.seul.org/pub/geda/dist/gnucap-0.32.tar.gz http://www.geda.seul.org/dist/gnucap-0.32.tar.gz ftp://sunsite.unc.edu/pub/Linux/apps/circuits/gnucap-0.32.tar.gz doc/relnotes.034000066400000000000000000000035101145401216200137010ustar00rootroot00000000000000Gnucap 0.34 release notes (02/01/2004) This is a bug fix and compatibility release. 1. Fix bug causing incorrect interpolation of backwards tables. 2. Fix tanh overflow bug. 3. Fix some parsing bugs. 4. Fix occasional "double load" bug. 5. Fix AC sweep with one point. 6. Transient start time really works. 7. Fix occasional assert fail after option short is changed. 8. Fix memory leak resulting from failure to delete unused common. 9. Fix a Z probe bug that sometimes gave wrong answers. 10. Fix a limiting bug that sometimes caused non-convergence. 11. Configure handles isnan. 12. Improvements to logic initialization. It is still not correct. Some things that are still partially implemented: 1. BSIM models, charge effects, "alpha0" parameter. (computed then ignored) 2. Configure still doesn't handle everything. 3. The model compiler still requires too much raw coding. 4. Named nodes. If you set the option "namednodes", it will support named nodes, but some things don't work, so it is off by default. 5. The preliminary IBIS code is now included. For now, it is a standalone executable, that reads an IBIS file and generates a netlist. The netlist requires some editing to use, and is not fully compatible anyway. It is included in hopes of recruiting help in finishing the project. Bugs (nothing new, but needs repeating): 1. The transmission line initial conditions are not propagated until the transient analysis runs. 2. An occasional bogus calculation in MOSFETS occurs when a device is reversed. This sometimes causes nonconvergence. 3. Initialization is strange when repeating an analysis without an intermediate edit. Hot items for a future release (no promises, but highly probable): 1. Verilog-AMS and VHDL-AMS support. doc/whatisit000066400000000000000000000064361145401216200134070ustar00rootroot00000000000000ACS is a general purpose circuit simulator. It performs nonlinear dc and transient analyses, fourier analysis, and ac analysis linearized at an operating point. It is fully interactive and command driven. It can also be run in batch mode or as a server. The output is produced as it simulates. Spice compatible models for the MOSFET (level 1-7) and diode are included in this release. ACS is not based on Berkeley Spice, but some of the models have been derived from the Berleley models. Since it is fully interactive, it is possible to make changes and re-simulate quickly. The interactive design makes it well suited to the typical iterative design process used it optimizing a circuit design. It is also well suited to undergraduate teaching where Spice in batch mode can be quite intimidating. This version, while still officially in beta test, should be stable enough for basic undergraduate teaching and courses in MOS design, but not for bipolar design. In batch mode it is mostly Spice compatible, so it is often possible to use the same file for both ACS and Spice. The analog simulation is based on traditional nodal analysis with iteration by Newton's method and LU decomposition. An event queue and incremental matrix update speed up the solution for large circuits (at some expense for small circuits). It also has digital devices for mixed signal simulation. The digital devices may be implemented as either analog subcircuits or as true digital models. The simulator will automatically determine which to use. Networks of digital devices are simulated as digital, with no conversions to analog between gates. This results in digital circuits being simulated faster than on a typical analog simulator, even with behavioral models. The digital mode is experimental and needs work. There will be substantial improvements in future releases. ACS also has a simple behavioral modeling language that allows simple behavioral descriptions of most components including capacitors and inductors. ACS uses an object oriented approach to modeling. Complex models like MOSFETS are made of simpler ones like resistors, capacitors, diodes, and any other models that may already exist. The model designer does not need to worry about details like convergence checking, bypass checking, integration, or how the new device plugs into the solution matrix because these are already taken care of by the basic models. In addition to this, a model generator automates the most tedious and most simulator dependent parts. This results in a dramatic improvement in the time it takes a researcher or model designer to install a new model, compared to Spice. If you are tired of Spice and want a second opinion, you want to play with the circuit and want a simulator that is interactive, or you want to study the source code and want something easier to follow than Spice, try ACS. ACS is an ongoing research project. It is being released in a preliminary phase in hopes that it will be useful and that others will use it as a thrust or base for their research. I also hope for some comments that may help me direct my research. ACS ftp sites: ftp://sunsite.unc.edu/pub/Linux/apps/circuits/acs-0.27.tar.gz ftp://ftp.geda.seul.org/pub/geda/dist/acs-0.27.tar.gz http://www.geda.seul.org/dist/acs-0.27.tar.gz Albert Davis aldavis@ieee.org examples/000077500000000000000000000000001145401216200126705ustar00rootroot00000000000000examples/Makefile.am000066400000000000000000000013401145401216200147220ustar00rootroot00000000000000## $Id$ ## pkgexamplesdir= ${pkgdatadir}/examples dist_pkgexamples_DATA= ${EXFILES} ##EXFILES= *.c *.doc *.ckt runall runall.out EXFILES= \ eq.doc eq2-145.ckt eq2-289.ckt eq2-577.ckt eq3-1153.ckt eq4-2305.ckt \ eq4-4609.ckt eq4-6913.ckt eq4-9217.ckt eq4-9217.tran-slow.ckt \ eq4-9217.tran.ckt eq5-.ac.ckt eq5-.tran.ckt eq5-.tran.euler.fast.ckt \ eq5-.tran.fast.ckt eq5-.tran.like-spice.ckt eq5-.tran.slow.ckt \ eq5-.tran.vfast.ckt eq5-.tran.vvfast.ckt eq5-.tran.vvvfast.ckt \ eq6-.tran.vvvfast.ckt eq7-.tran.vvvfast.ckt eqboost.ckt eqflat.ckt \ eqmodify.ckt killzap.ckt killzap.doc nmos.doc nmos100.ckt nmos15.ckt \ nmos18.ckt nmos30.ckt nmosgen.c nmp100.ckt nmpgen.c opamp-ol.ckt \ opamp-vf.ckt opamp.doc runall runall.out sc18.ckt examples/Makefile.in000066400000000000000000000263771145401216200147540ustar00rootroot00000000000000# Makefile.in generated by automake 1.11 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = examples DIST_COMMON = README $(dist_pkgexamples_DATA) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(pkgexamplesdir)" DATA = $(dist_pkgexamples_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EXEEXT = @EXEEXT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MODELGEN = @MODELGEN@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkgexamplesdir = ${pkgdatadir}/examples dist_pkgexamples_DATA = ${EXFILES} EXFILES = \ eq.doc eq2-145.ckt eq2-289.ckt eq2-577.ckt eq3-1153.ckt eq4-2305.ckt \ eq4-4609.ckt eq4-6913.ckt eq4-9217.ckt eq4-9217.tran-slow.ckt \ eq4-9217.tran.ckt eq5-.ac.ckt eq5-.tran.ckt eq5-.tran.euler.fast.ckt \ eq5-.tran.fast.ckt eq5-.tran.like-spice.ckt eq5-.tran.slow.ckt \ eq5-.tran.vfast.ckt eq5-.tran.vvfast.ckt eq5-.tran.vvvfast.ckt \ eq6-.tran.vvvfast.ckt eq7-.tran.vvvfast.ckt eqboost.ckt eqflat.ckt \ eqmodify.ckt killzap.ckt killzap.doc nmos.doc nmos100.ckt nmos15.ckt \ nmos18.ckt nmos30.ckt nmosgen.c nmp100.ckt nmpgen.c opamp-ol.ckt \ opamp-vf.ckt opamp.doc runall runall.out sc18.ckt all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu examples/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-dist_pkgexamplesDATA: $(dist_pkgexamples_DATA) @$(NORMAL_INSTALL) test -z "$(pkgexamplesdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgexamplesdir)" @list='$(dist_pkgexamples_DATA)'; test -n "$(pkgexamplesdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgexamplesdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgexamplesdir)" || exit $$?; \ done uninstall-dist_pkgexamplesDATA: @$(NORMAL_UNINSTALL) @list='$(dist_pkgexamples_DATA)'; test -n "$(pkgexamplesdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(pkgexamplesdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(pkgexamplesdir)" && rm -f $$files tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(pkgexamplesdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_pkgexamplesDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_pkgexamplesDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-dist_pkgexamplesDATA install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am uninstall uninstall-am \ uninstall-dist_pkgexamplesDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: examples/README000066400000000000000000000012561145401216200135540ustar00rootroot00000000000000Here are some ACS example circuits. Some of these will also run on Spice and can be used for comparison. You can run them in batch mode by typing "acs -b name" from the shell. You can run them interactively by starting acs then "get name". Then play, change probes, rerun, change values, etc. The file "runall" is a script so you can automate the testing. Read it before using it. "runall.out" is the result of running "runall". Ideally, you should get identical results, but there are often small differences in the machine math functions that will give small differences in the results. Any numerically significant difference represents a serious bug and should be addressed. examples/eq.doc000066400000000000000000000017101145401216200137630ustar00rootroot00000000000000There a whole bunch of "eq" circuits of various types and more are coming. This is a 10 band graphic equalizer that I have used as a benchmark since my early days of working on simulation. I have it in more forms that are not here. By using different models for op-amps, cascading them, and other tricks I have used it to test just about everything. This is a working product of my design that was (and may still be) very popular among record producers in the late 70's and early 80's. It was designed using a predecessor to ACS on a TRS-80. eqboost.ckt the 1k band is boosted 12 db eqflat.ckt all bands are set flat eqmodify.ckt both. run it batch. eq?-????.ckt A bunch of them cascaded to test the sparse matrix. Try these on Spice if you have lots of CPU time. ACS time growth is almost linear. Spice-2 growth is quadratic. These probably won't work on a PC. The biggest one has over 9000 nodes. Don't bother with them on MSDOS. Not enough memory. examples/eq2-145.ckt000066400000000000000000000040321145401216200143700ustar00rootroot00000000000000A 145 node circuit Vin 1 0 dc 1 ac 1 x1 1 2 eq4 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq .print op iter(0) v(1) v(2) .print dc v(2) .print ac vm(2) vdb(2) vp(2) .dc Vin 1 10 1 .ac oct 1 31.25 16000 .end examples/eq2-289.ckt000066400000000000000000000040521145401216200144030ustar00rootroot00000000000000A 289 node circuit Vin 1 0 dc 1 ac 1 x1 1 2 eq4 x2 2 3 eq4 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq .print op iter(0) v(1) v(2) v(3) .print dc v(2) .print ac vm(2) vdb(2) vp(2) .dc Vin 1 10 1 .ac oct 1 31.25 16000 .end examples/eq2-577.ckt000066400000000000000000000041121145401216200144000ustar00rootroot00000000000000A 577 node circuit Vin 1 0 dc 1 ac 1 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq .print op iter(0) v(1) v(2) v(3) v(4) v(5) .print dc v(2) .print ac vm(2) vdb(2) vp(2) .dc Vin 1 10 1 .ac oct 1 31.25 16000 .end examples/eq3-1153.ckt000066400000000000000000000042301145401216200144510ustar00rootroot00000000000000A 1153 node circuit Vin 1 0 dc 1 ac 1 x1 1 2 eq32 .subckt eq32 1 3 x1 1 2 eq16 x2 2 3 eq16 .ends eq32 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq .print op iter(0) v(1) v(2) .print dc v(2) .print ac vm(2) vdb(2) vp(2) .dc Vin 1 10 1 .ac oct 1 31.25 16000 .end examples/eq4-2305.ckt000066400000000000000000000042601145401216200144550ustar00rootroot00000000000000A 2305 node circuit Vin 1 0 dc 1 ac 1 x1 1 2 eq64 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq .print op iter(0) v(1) v(2) .print dc v(2) .print ac vm(2) vdb(2) vp(2) .dc Vin 1 10 1 .ac oct 1 31.25 16000 .end examples/eq4-4609.ckt000066400000000000000000000043011145401216200144620ustar00rootroot00000000000000A 4609 node circuit Vin 1 0 dc 1 ac 1 x1 1 2 eq64 x2 2 3 eq64 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq .print op iter(0) v(1) v(2) v(3) .print dc v(2) .print ac vm(2) vdb(2) vp(2) .dc Vin 1 10 1 .ac oct 1 31.25 16000 .end examples/eq4-6913.ckt000066400000000000000000000043221145401216200144650ustar00rootroot00000000000000A 6913 node circuit Vin 1 0 dc 1 ac 1 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq .print op iter(0) v(1) v(2) v(3) v(4) .print dc v(2) .print ac vm(2) vdb(2) vp(2) .dc Vin 1 10 1 .ac oct 1 31.25 16000 .end examples/eq4-9217.ckt000066400000000000000000000043431145401216200144700ustar00rootroot00000000000000A 9217 node circuit Vin 1 0 dc 1 ac 1 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq .print op iter(0) v(1) v(2) v(3) v(4) v(5) .print dc v(2) .print ac vm(2) vdb(2) vp(2) .dc Vin 1 10 1 .ac oct 1 31.25 16000 .end examples/eq4-9217.tran-slow.ckt000066400000000000000000000042761145401216200164220ustar00rootroot00000000000000A 9217 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall noincmode nobypass .print tran v(5) .tran .00001 .001 0 .end examples/eq4-9217.tran.ckt000066400000000000000000000042531145401216200154330ustar00rootroot00000000000000A 9217 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall .print tran v(5) .tran .00001 .001 0 .end examples/eq5-.ac.ckt000066400000000000000000000044321145401216200145270ustar00rootroot00000000000000A 36865 node circuit Vin 1 0 dc sin 0 1 1k 0 0 ac 1 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall *>.print op v(nodes) .op .print ac v(5) .ac oct 2 31.25 16k .end examples/eq5-.tran.ckt000066400000000000000000000043761145401216200151170ustar00rootroot00000000000000A 36865 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall .print tran v(5) .tran .00001 .001 0 .end examples/eq5-.tran.euler.fast.ckt000066400000000000000000000044251145401216200171610ustar00rootroot00000000000000A 36865 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall itermin=0 method=euler .print tran v(5) .tran .00001 .001 0 .end examples/eq5-.tran.fast.ckt000066400000000000000000000044101145401216200160400ustar00rootroot00000000000000A 36865 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall itermin=0 .print tran v(5) .tran .00001 .001 0 .end examples/eq5-.tran.like-spice.ckt000066400000000000000000000045071145401216200171370ustar00rootroot00000000000000A 36865 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall noincmode nobypass notraceload nolubypass nofbbypass *>.option itermin=0 .print tran v(5) .tran .00002 .001 0 .end examples/eq5-.tran.slow.ckt000066400000000000000000000044631145401216200160770ustar00rootroot00000000000000A 36865 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall noincmode nobypass notraceload nolubypass nofbbypass .print tran v(5) .tran .00001 .001 0 .end examples/eq5-.tran.vfast.ckt000066400000000000000000000044101145401216200162260ustar00rootroot00000000000000A 36865 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall itermin=0 .print tran v(5) .tran .00002 .001 0 .end examples/eq5-.tran.vvfast.ckt000066400000000000000000000044101145401216200164140ustar00rootroot00000000000000A 36865 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall itermin=0 .print tran v(5) .tran .00005 .001 0 .end examples/eq5-.tran.vvvfast.ckt000066400000000000000000000044251145401216200166100ustar00rootroot00000000000000A 36865 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall itermin=0 method=euler .print tran v(5) .tran .00005 .001 0 .end examples/eq6-.tran.vvvfast.ckt000066400000000000000000000045561145401216200166160ustar00rootroot00000000000000A 147457 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq1024 x2 2 3 eq1024 x3 3 4 eq1024 x4 4 5 eq1024 .subckt eq1024 1 5 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .ends eq1024 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall itermin=0 method=euler .print tran v(5) .tran .00005 .001 0 .end examples/eq7-.tran.default.ckt000066400000000000000000000046571145401216200165460ustar00rootroot00000000000000A 589825 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq4096 x2 2 3 eq4096 x3 3 4 eq4096 x4 4 5 eq4096 .subckt eq4096 1 5 x1 1 2 eq1024 x2 2 3 eq1024 x3 3 4 eq1024 x4 4 5 eq1024 .ends eq4096 .subckt eq1024 1 5 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .ends eq1024 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall .print tran v(5) .tran .00005 .001 0 .end examples/eq7-.tran.nobypass.ckt000066400000000000000000000046701145401216200167530ustar00rootroot00000000000000A 589825 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq4096 x2 2 3 eq4096 x3 3 4 eq4096 x4 4 5 eq4096 .subckt eq4096 1 5 x1 1 2 eq1024 x2 2 3 eq1024 x3 3 4 eq1024 x4 4 5 eq1024 .ends eq4096 .subckt eq1024 1 5 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .ends eq1024 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall nobypass .print tran v(5) .tran .00005 .001 0 .end examples/eq7-.tran.nofbbypass.ckt000066400000000000000000000046721145401216200172650ustar00rootroot00000000000000A 589825 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq4096 x2 2 3 eq4096 x3 3 4 eq4096 x4 4 5 eq4096 .subckt eq4096 1 5 x1 1 2 eq1024 x2 2 3 eq1024 x3 3 4 eq1024 x4 4 5 eq1024 .ends eq4096 .subckt eq1024 1 5 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .ends eq1024 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall nofbbypass .print tran v(5) .tran .00005 .001 0 .end examples/eq7-.tran.noincmode.ckt000066400000000000000000000046711145401216200170710ustar00rootroot00000000000000A 589825 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq4096 x2 2 3 eq4096 x3 3 4 eq4096 x4 4 5 eq4096 .subckt eq4096 1 5 x1 1 2 eq1024 x2 2 3 eq1024 x3 3 4 eq1024 x4 4 5 eq1024 .ends eq4096 .subckt eq1024 1 5 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .ends eq1024 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall noincmode .print tran v(5) .tran .00005 .001 0 .end examples/eq7-.tran.nolcbypass.ckt000066400000000000000000000046721145401216200172740ustar00rootroot00000000000000A 589825 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq4096 x2 2 3 eq4096 x3 3 4 eq4096 x4 4 5 eq4096 .subckt eq4096 1 5 x1 1 2 eq1024 x2 2 3 eq1024 x3 3 4 eq1024 x4 4 5 eq1024 .ends eq4096 .subckt eq1024 1 5 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .ends eq1024 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall nolcbypass .print tran v(5) .tran .00005 .001 0 .end examples/eq7-.tran.nolubypass.ckt000066400000000000000000000046721145401216200173160ustar00rootroot00000000000000A 589825 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq4096 x2 2 3 eq4096 x3 3 4 eq4096 x4 4 5 eq4096 .subckt eq4096 1 5 x1 1 2 eq1024 x2 2 3 eq1024 x3 3 4 eq1024 x4 4 5 eq1024 .ends eq4096 .subckt eq1024 1 5 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .ends eq1024 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall nolubypass .print tran v(5) .tran .00005 .001 0 .end examples/eq7-.tran.notraceload.ckt000066400000000000000000000046731145401216200174130ustar00rootroot00000000000000A 589825 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq4096 x2 2 3 eq4096 x3 3 4 eq4096 x4 4 5 eq4096 .subckt eq4096 1 5 x1 1 2 eq1024 x2 2 3 eq1024 x3 3 4 eq1024 x4 4 5 eq1024 .ends eq4096 .subckt eq1024 1 5 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .ends eq1024 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall notraceload .print tran v(5) .tran .00005 .001 0 .end examples/eq7-.tran.slow.ckt000066400000000000000000000047571145401216200161070ustar00rootroot00000000000000A 589825 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq4096 x2 2 3 eq4096 x3 3 4 eq4096 x4 4 5 eq4096 .subckt eq4096 1 5 x1 1 2 eq1024 x2 2 3 eq1024 x3 3 4 eq1024 x4 4 5 eq1024 .ends eq4096 .subckt eq1024 1 5 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .ends eq1024 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall nobypass noincmode nolcbypass nolubypass nofbbypass notraceload .print tran v(5) .tran .00005 .001 0 .end examples/eq7-.tran.spice-accurate.ckt000066400000000000000000000046711145401216200200060ustar00rootroot00000000000000A 589825 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq4096 x2 2 3 eq4096 x3 3 4 eq4096 x4 4 5 eq4096 .subckt eq4096 1 5 x1 1 2 eq1024 x2 2 3 eq1024 x3 3 4 eq1024 x4 4 5 eq1024 .ends eq4096 .subckt eq1024 1 5 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .ends eq1024 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall itermin=0 .print tran v(5) .tran .00005 .001 0 .end examples/eq7-.tran.vvvfast.ckt000066400000000000000000000047061145401216200166140ustar00rootroot00000000000000A 589825 node circuit Vin 1 0 dc sin 0 1 1k 0 0 x1 1 2 eq4096 x2 2 3 eq4096 x3 3 4 eq4096 x4 4 5 eq4096 .subckt eq4096 1 5 x1 1 2 eq1024 x2 2 3 eq1024 x3 3 4 eq1024 x4 4 5 eq1024 .ends eq4096 .subckt eq1024 1 5 x1 1 2 eq256 x2 2 3 eq256 x3 3 4 eq256 x4 4 5 eq256 .ends eq1024 .subckt eq256 1 5 x1 1 2 eq64 x2 2 3 eq64 x3 3 4 eq64 x4 4 5 eq64 .ends eq256 .subckt eq64 1 5 x1 1 2 eq16 x2 2 3 eq16 x3 3 4 eq16 x4 4 5 eq16 .ends eq64 .subckt eq16 1 5 x1 1 2 eq4 x2 2 3 eq4 x3 3 4 eq4 x4 4 5 eq4 .ends eq16 .subckt eq4 1 5 x1 1 2 eq x2 2 3 eq x3 3 4 eq x4 4 5 eq .ends eq4 .subckt eq 31 37 R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p E2 34 0 32 33 10.K E3 37 0 35 36 10.K .ends eq *>.option acct showall itermin=0 method=euler .print tran v(5) .tran .00005 .001 0 .end examples/eqboost.ckt000066400000000000000000000036141145401216200150530ustar00rootroot00000000000000Graphic equalizer -- boost 1k R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 100.K R106b 33 16 1 R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p Vin 31 0 dc 1 ac 1 E2 34 0 32 33 10.K E3 37 0 35 36 10.K .print ac vdb(37) vdb(31) vdb(34) .ac oct 4 31.25 32k .end examples/eqflat.ckt000066400000000000000000000036411145401216200146530ustar00rootroot00000000000000Graphic equalizer -- all bands flat, modify test R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p Vin 31 0 dc 1 ac 1 E2 34 0 32 33 10.K E3 37 0 35 36 10.K .print ac vdb(37) vdb(31) vdb(34) .ac oct 4 31.25 32k .end examples/eqmodify.ckt000066400000000000000000000037101145401216200152110ustar00rootroot00000000000000Graphic equalizer -- all bands flat, modify test R101a 35 1 50.K R101b 36 1 50.K R102a 32 4 50.K R102b 33 4 50.K R103a 35 7 50.K R103b 36 7 50.K R104a 32 10 50.K R104b 33 10 50.K R105a 35 13 50.K R105b 36 13 50.K R106a 32 16 50.K R106b 33 16 50.K R107a 35 19 50.K R107b 36 19 50.K R108a 32 22 50.K R108b 33 22 50.K R109a 35 25 50.K R109b 36 25 50.K R110a 32 28 50.K R110b 33 28 50.K C1 1 2 1.5u C2 4 5 748.n C3 7 8 408.n C4 10 11 206.n C5 13 14 100.n C6 16 17 50.9n C7 19 20 25.3n C8 22 23 12.7n C9 25 26 5.9n C10 28 29 2.95n C11 2 3 15.n C12 5 6 6.8n C13 8 9 3.3n C14 11 12 1.8n C15 14 15 1.n C16 17 18 470.p C17 20 21 220.p C18 23 24 120.p C19 26 27 68.p C20 29 30 33.p R1 3 0 475.K R2 6 0 536.K R3 9 0 549.K R4 12 0 499.K R5 15 0 464.K R6 18 0 475.K R7 21 0 523.K R8 24 0 475.K R9 27 0 412.K R10 30 0 422.K G5a 2 0 3 0 -.000416666 R11 2 0 2.4K G5b 5 0 6 0 -.000416666 R12 5 0 2.4K G6a 8 0 9 0 -.000454545 R13 8 0 2.2K G6b 11 0 12 0 -.000454545 R14 11 0 2.2K G7a 14 0 15 0 -.000454545 R15 14 0 2.2K G7b 17 0 18 0 -.000454545 R16 17 0 2.2K G8a 20 0 21 0 -.000454545 R17 20 0 2.2K G8b 23 0 24 0 -.000454545 R18 23 0 2.2K G9a 26 0 27 0 -.000416666 R19 26 0 2.4K G9b 29 0 30 0 -.000416666 R20 29 0 2.4K R29 31 32 9.1K R30 33 34 9.1K R31 34 35 9.1K R32 36 37 9.1K C25 31 32 150.p C26 33 34 150.p C27 34 35 150.p C28 36 37 150.p Vin 31 0 dc 1 ac 1 E2 34 0 32 33 10.K E3 37 0 35 36 10.K .print ac vdb(37) vdb(31) vdb(34) .ac oct 4 31.25 32k .modify R106a=100k .modify R106b=1 .ac .end examples/killzap.ckt000066400000000000000000000001761145401216200150450ustar00rootroot00000000000000' V1 1 0 ac 1. R2 1 2 1. C3 2 0 complex( 0. 1. ) .print ac vm(2) vdb(2) vp(2) .ac 1p 1g dec .ac .1 .2 .005 .end examples/killzap.doc000066400000000000000000000005151145401216200150260ustar00rootroot00000000000000This "circuit" has a transfer function of 1 / (js+1). There is one complex pole at (-1,1). The capacitor value is j1. It has an interesting frequency response. The original purpose was to trick another program "zap" (zeros and poles) into giving bogus answers. It did!! We all know that poles come in conjugate pairs..... AC only! examples/nmos.doc000066400000000000000000000020241145401216200143310ustar00rootroot00000000000000Here are a few strings of NMOS inverters. NMOS is harder to simulate than CMOS. nmos22.ckt all one power supply nmos30.ckt nmos100.ckt nmp100.ckt separate power supplies The number is the number of gates. Power supply coupling can hinder convergence, so the big circuits have separate power supplies for each gate. At 1000 gates it makes the difference between convergence and non-convergence. At 100 gates, it slows it down a bit but doesn't change the number of iterations. The latency exploitation doesn't work as well with common power supplies. The reason for the problem is that the voltage source in ACS is non-ideal. A future release will have an ideal voltage source. Still... Spice 2g6 doesn't converge on either 100 gate circuit. Another point is that these large circuits show why ACS doesn't automatically print everything when you do an "op" analysis. Everything Spice gives you is available. We just don't print it automatically. The two .c files nmosgen.c and nmpgen.c are what I used to generate these circuits. examples/nmos100.ckt000066400000000000000000000156051145401216200145770ustar00rootroot00000000000000100 cascaded NMOS inverters md1 3 2 0 0 modeld w=10u l=2u ml1 1 1 3 0 modell w=2u l=2u md2 4 3 0 0 modeld w=10u l=2u ml2 1 1 4 0 modell w=2u l=2u md3 5 4 0 0 modeld w=10u l=2u ml3 1 1 5 0 modell w=2u l=2u md4 6 5 0 0 modeld w=10u l=2u ml4 1 1 6 0 modell w=2u l=2u md5 7 6 0 0 modeld w=10u l=2u ml5 1 1 7 0 modell w=2u l=2u md6 8 7 0 0 modeld w=10u l=2u ml6 1 1 8 0 modell w=2u l=2u md7 9 8 0 0 modeld w=10u l=2u ml7 1 1 9 0 modell w=2u l=2u md8 10 9 0 0 modeld w=10u l=2u ml8 1 1 10 0 modell w=2u l=2u md9 11 10 0 0 modeld w=10u l=2u ml9 1 1 11 0 modell w=2u l=2u md10 12 11 0 0 modeld w=10u l=2u ml10 1 1 12 0 modell w=2u l=2u md11 13 12 0 0 modeld w=10u l=2u ml11 1 1 13 0 modell w=2u l=2u md12 14 13 0 0 modeld w=10u l=2u ml12 1 1 14 0 modell w=2u l=2u md13 15 14 0 0 modeld w=10u l=2u ml13 1 1 15 0 modell w=2u l=2u md14 16 15 0 0 modeld w=10u l=2u ml14 1 1 16 0 modell w=2u l=2u md15 17 16 0 0 modeld w=10u l=2u ml15 1 1 17 0 modell w=2u l=2u md16 18 17 0 0 modeld w=10u l=2u ml16 1 1 18 0 modell w=2u l=2u md17 19 18 0 0 modeld w=10u l=2u ml17 1 1 19 0 modell w=2u l=2u md18 20 19 0 0 modeld w=10u l=2u ml18 1 1 20 0 modell w=2u l=2u md19 21 20 0 0 modeld w=10u l=2u ml19 1 1 21 0 modell w=2u l=2u md20 22 21 0 0 modeld w=10u l=2u ml20 1 1 22 0 modell w=2u l=2u md21 23 22 0 0 modeld w=10u l=2u ml21 1 1 23 0 modell w=2u l=2u md22 24 23 0 0 modeld w=10u l=2u ml22 1 1 24 0 modell w=2u l=2u md23 25 24 0 0 modeld w=10u l=2u ml23 1 1 25 0 modell w=2u l=2u md24 26 25 0 0 modeld w=10u l=2u ml24 1 1 26 0 modell w=2u l=2u md25 27 26 0 0 modeld w=10u l=2u ml25 1 1 27 0 modell w=2u l=2u md26 28 27 0 0 modeld w=10u l=2u ml26 1 1 28 0 modell w=2u l=2u md27 29 28 0 0 modeld w=10u l=2u ml27 1 1 29 0 modell w=2u l=2u md28 30 29 0 0 modeld w=10u l=2u ml28 1 1 30 0 modell w=2u l=2u md29 31 30 0 0 modeld w=10u l=2u ml29 1 1 31 0 modell w=2u l=2u md30 32 31 0 0 modeld w=10u l=2u ml30 1 1 32 0 modell w=2u l=2u md31 33 32 0 0 modeld w=10u l=2u ml31 1 1 33 0 modell w=2u l=2u md32 34 33 0 0 modeld w=10u l=2u ml32 1 1 34 0 modell w=2u l=2u md33 35 34 0 0 modeld w=10u l=2u ml33 1 1 35 0 modell w=2u l=2u md34 36 35 0 0 modeld w=10u l=2u ml34 1 1 36 0 modell w=2u l=2u md35 37 36 0 0 modeld w=10u l=2u ml35 1 1 37 0 modell w=2u l=2u md36 38 37 0 0 modeld w=10u l=2u ml36 1 1 38 0 modell w=2u l=2u md37 39 38 0 0 modeld w=10u l=2u ml37 1 1 39 0 modell w=2u l=2u md38 40 39 0 0 modeld w=10u l=2u ml38 1 1 40 0 modell w=2u l=2u md39 41 40 0 0 modeld w=10u l=2u ml39 1 1 41 0 modell w=2u l=2u md40 42 41 0 0 modeld w=10u l=2u ml40 1 1 42 0 modell w=2u l=2u md41 43 42 0 0 modeld w=10u l=2u ml41 1 1 43 0 modell w=2u l=2u md42 44 43 0 0 modeld w=10u l=2u ml42 1 1 44 0 modell w=2u l=2u md43 45 44 0 0 modeld w=10u l=2u ml43 1 1 45 0 modell w=2u l=2u md44 46 45 0 0 modeld w=10u l=2u ml44 1 1 46 0 modell w=2u l=2u md45 47 46 0 0 modeld w=10u l=2u ml45 1 1 47 0 modell w=2u l=2u md46 48 47 0 0 modeld w=10u l=2u ml46 1 1 48 0 modell w=2u l=2u md47 49 48 0 0 modeld w=10u l=2u ml47 1 1 49 0 modell w=2u l=2u md48 50 49 0 0 modeld w=10u l=2u ml48 1 1 50 0 modell w=2u l=2u md49 51 50 0 0 modeld w=10u l=2u ml49 1 1 51 0 modell w=2u l=2u md50 52 51 0 0 modeld w=10u l=2u ml50 1 1 52 0 modell w=2u l=2u md51 53 52 0 0 modeld w=10u l=2u ml51 1 1 53 0 modell w=2u l=2u md52 54 53 0 0 modeld w=10u l=2u ml52 1 1 54 0 modell w=2u l=2u md53 55 54 0 0 modeld w=10u l=2u ml53 1 1 55 0 modell w=2u l=2u md54 56 55 0 0 modeld w=10u l=2u ml54 1 1 56 0 modell w=2u l=2u md55 57 56 0 0 modeld w=10u l=2u ml55 1 1 57 0 modell w=2u l=2u md56 58 57 0 0 modeld w=10u l=2u ml56 1 1 58 0 modell w=2u l=2u md57 59 58 0 0 modeld w=10u l=2u ml57 1 1 59 0 modell w=2u l=2u md58 60 59 0 0 modeld w=10u l=2u ml58 1 1 60 0 modell w=2u l=2u md59 61 60 0 0 modeld w=10u l=2u ml59 1 1 61 0 modell w=2u l=2u md60 62 61 0 0 modeld w=10u l=2u ml60 1 1 62 0 modell w=2u l=2u md61 63 62 0 0 modeld w=10u l=2u ml61 1 1 63 0 modell w=2u l=2u md62 64 63 0 0 modeld w=10u l=2u ml62 1 1 64 0 modell w=2u l=2u md63 65 64 0 0 modeld w=10u l=2u ml63 1 1 65 0 modell w=2u l=2u md64 66 65 0 0 modeld w=10u l=2u ml64 1 1 66 0 modell w=2u l=2u md65 67 66 0 0 modeld w=10u l=2u ml65 1 1 67 0 modell w=2u l=2u md66 68 67 0 0 modeld w=10u l=2u ml66 1 1 68 0 modell w=2u l=2u md67 69 68 0 0 modeld w=10u l=2u ml67 1 1 69 0 modell w=2u l=2u md68 70 69 0 0 modeld w=10u l=2u ml68 1 1 70 0 modell w=2u l=2u md69 71 70 0 0 modeld w=10u l=2u ml69 1 1 71 0 modell w=2u l=2u md70 72 71 0 0 modeld w=10u l=2u ml70 1 1 72 0 modell w=2u l=2u md71 73 72 0 0 modeld w=10u l=2u ml71 1 1 73 0 modell w=2u l=2u md72 74 73 0 0 modeld w=10u l=2u ml72 1 1 74 0 modell w=2u l=2u md73 75 74 0 0 modeld w=10u l=2u ml73 1 1 75 0 modell w=2u l=2u md74 76 75 0 0 modeld w=10u l=2u ml74 1 1 76 0 modell w=2u l=2u md75 77 76 0 0 modeld w=10u l=2u ml75 1 1 77 0 modell w=2u l=2u md76 78 77 0 0 modeld w=10u l=2u ml76 1 1 78 0 modell w=2u l=2u md77 79 78 0 0 modeld w=10u l=2u ml77 1 1 79 0 modell w=2u l=2u md78 80 79 0 0 modeld w=10u l=2u ml78 1 1 80 0 modell w=2u l=2u md79 81 80 0 0 modeld w=10u l=2u ml79 1 1 81 0 modell w=2u l=2u md80 82 81 0 0 modeld w=10u l=2u ml80 1 1 82 0 modell w=2u l=2u md81 83 82 0 0 modeld w=10u l=2u ml81 1 1 83 0 modell w=2u l=2u md82 84 83 0 0 modeld w=10u l=2u ml82 1 1 84 0 modell w=2u l=2u md83 85 84 0 0 modeld w=10u l=2u ml83 1 1 85 0 modell w=2u l=2u md84 86 85 0 0 modeld w=10u l=2u ml84 1 1 86 0 modell w=2u l=2u md85 87 86 0 0 modeld w=10u l=2u ml85 1 1 87 0 modell w=2u l=2u md86 88 87 0 0 modeld w=10u l=2u ml86 1 1 88 0 modell w=2u l=2u md87 89 88 0 0 modeld w=10u l=2u ml87 1 1 89 0 modell w=2u l=2u md88 90 89 0 0 modeld w=10u l=2u ml88 1 1 90 0 modell w=2u l=2u md89 91 90 0 0 modeld w=10u l=2u ml89 1 1 91 0 modell w=2u l=2u md90 92 91 0 0 modeld w=10u l=2u ml90 1 1 92 0 modell w=2u l=2u md91 93 92 0 0 modeld w=10u l=2u ml91 1 1 93 0 modell w=2u l=2u md92 94 93 0 0 modeld w=10u l=2u ml92 1 1 94 0 modell w=2u l=2u md93 95 94 0 0 modeld w=10u l=2u ml93 1 1 95 0 modell w=2u l=2u md94 96 95 0 0 modeld w=10u l=2u ml94 1 1 96 0 modell w=2u l=2u md95 97 96 0 0 modeld w=10u l=2u ml95 1 1 97 0 modell w=2u l=2u md96 98 97 0 0 modeld w=10u l=2u ml96 1 1 98 0 modell w=2u l=2u md97 99 98 0 0 modeld w=10u l=2u ml97 1 1 99 0 modell w=2u l=2u md98 100 99 0 0 modeld w=10u l=2u ml98 1 1 100 0 modell w=2u l=2u md99 101 100 0 0 modeld w=10u l=2u ml99 1 1 101 0 modell w=2u l=2u md100 102 101 0 0 modeld w=10u l=2u ml100 1 1 102 0 modell w=2u l=2u vdd 1 0 5 vin 2 0 .8 .MODEL MODELD NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5) .MODEL MODELL NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5) .PRINT OP iter(0) V(nodes) .option vmin=-.1 short=1u dampstrategy=10 .op .end examples/nmos15.ckt000066400000000000000000000022741145401216200145220ustar00rootroot0000000000000015 cascaded NMOS inverters md1 3 2 0 0 modeld w=10u l=2u ml1 1 1 3 0 modell w=2u l=2u md2 4 3 0 0 modeld w=10u l=2u ml2 1 1 4 0 modell w=2u l=2u md3 5 4 0 0 modeld w=10u l=2u ml3 1 1 5 0 modell w=2u l=2u md4 6 5 0 0 modeld w=10u l=2u ml4 1 1 6 0 modell w=2u l=2u md5 7 6 0 0 modeld w=10u l=2u ml5 1 1 7 0 modell w=2u l=2u md6 8 7 0 0 modeld w=10u l=2u ml6 1 1 8 0 modell w=2u l=2u md7 9 8 0 0 modeld w=10u l=2u ml7 1 1 9 0 modell w=2u l=2u md8 10 9 0 0 modeld w=10u l=2u ml8 1 1 10 0 modell w=2u l=2u md9 11 10 0 0 modeld w=10u l=2u ml9 1 1 11 0 modell w=2u l=2u md10 12 11 0 0 modeld w=10u l=2u ml10 1 1 12 0 modell w=2u l=2u md11 13 12 0 0 modeld w=10u l=2u ml11 1 1 13 0 modell w=2u l=2u md12 14 13 0 0 modeld w=10u l=2u ml12 1 1 14 0 modell w=2u l=2u md13 15 14 0 0 modeld w=10u l=2u ml13 1 1 15 0 modell w=2u l=2u md14 16 15 0 0 modeld w=10u l=2u ml14 1 1 16 0 modell w=2u l=2u md15 17 16 0 0 modeld w=10u l=2u ml15 1 1 17 0 modell w=2u l=2u vdd 1 0 5 vin 2 0 .8 .MODEL MODELD NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5) .MODEL MODELL NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5) .PRINT OP iter(0) V(nodes) .op .end examples/nmos18.ckt000066400000000000000000000026101145401216200145170ustar00rootroot0000000000000018 cascaded NMOS inverters md1 3 2 0 0 modeld w=10u l=2u ml1 1 1 3 0 modell w=2u l=2u md2 4 3 0 0 modeld w=10u l=2u ml2 1 1 4 0 modell w=2u l=2u md3 5 4 0 0 modeld w=10u l=2u ml3 1 1 5 0 modell w=2u l=2u md4 6 5 0 0 modeld w=10u l=2u ml4 1 1 6 0 modell w=2u l=2u md5 7 6 0 0 modeld w=10u l=2u ml5 1 1 7 0 modell w=2u l=2u md6 8 7 0 0 modeld w=10u l=2u ml6 1 1 8 0 modell w=2u l=2u md7 9 8 0 0 modeld w=10u l=2u ml7 1 1 9 0 modell w=2u l=2u md8 10 9 0 0 modeld w=10u l=2u ml8 1 1 10 0 modell w=2u l=2u md9 11 10 0 0 modeld w=10u l=2u ml9 1 1 11 0 modell w=2u l=2u md10 12 11 0 0 modeld w=10u l=2u ml10 1 1 12 0 modell w=2u l=2u md11 13 12 0 0 modeld w=10u l=2u ml11 1 1 13 0 modell w=2u l=2u md12 14 13 0 0 modeld w=10u l=2u ml12 1 1 14 0 modell w=2u l=2u md13 15 14 0 0 modeld w=10u l=2u ml13 1 1 15 0 modell w=2u l=2u md14 16 15 0 0 modeld w=10u l=2u ml14 1 1 16 0 modell w=2u l=2u md15 17 16 0 0 modeld w=10u l=2u ml15 1 1 17 0 modell w=2u l=2u md16 18 17 0 0 modeld w=10u l=2u ml16 1 1 18 0 modell w=2u l=2u md17 19 18 0 0 modeld w=10u l=2u ml17 1 1 19 0 modell w=2u l=2u md18 20 19 0 0 modeld w=10u l=2u ml18 1 1 20 0 modell w=2u l=2u vdd 1 0 5 vin 2 0 .8 .MODEL MODELD NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5) .MODEL MODELL NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5) .PRINT OP iter(0) V(nodes) .op .end examples/nmos30.ckt000066400000000000000000000042701145401216200145150ustar00rootroot0000000000000030 cascaded NMOS inverters md1 3 2 0 0 modeld w=10u l=2u ml1 1 1 3 0 modell w=2u l=2u md2 4 3 0 0 modeld w=10u l=2u ml2 1 1 4 0 modell w=2u l=2u md3 5 4 0 0 modeld w=10u l=2u ml3 1 1 5 0 modell w=2u l=2u md4 6 5 0 0 modeld w=10u l=2u ml4 1 1 6 0 modell w=2u l=2u md5 7 6 0 0 modeld w=10u l=2u ml5 1 1 7 0 modell w=2u l=2u md6 8 7 0 0 modeld w=10u l=2u ml6 1 1 8 0 modell w=2u l=2u md7 9 8 0 0 modeld w=10u l=2u ml7 1 1 9 0 modell w=2u l=2u md8 10 9 0 0 modeld w=10u l=2u ml8 1 1 10 0 modell w=2u l=2u md9 11 10 0 0 modeld w=10u l=2u ml9 1 1 11 0 modell w=2u l=2u md10 12 11 0 0 modeld w=10u l=2u ml10 1 1 12 0 modell w=2u l=2u md11 13 12 0 0 modeld w=10u l=2u ml11 1 1 13 0 modell w=2u l=2u md12 14 13 0 0 modeld w=10u l=2u ml12 1 1 14 0 modell w=2u l=2u md13 15 14 0 0 modeld w=10u l=2u ml13 1 1 15 0 modell w=2u l=2u md14 16 15 0 0 modeld w=10u l=2u ml14 1 1 16 0 modell w=2u l=2u md15 17 16 0 0 modeld w=10u l=2u ml15 1 1 17 0 modell w=2u l=2u md16 18 17 0 0 modeld w=10u l=2u ml16 1 1 18 0 modell w=2u l=2u md17 19 18 0 0 modeld w=10u l=2u ml17 1 1 19 0 modell w=2u l=2u md18 20 19 0 0 modeld w=10u l=2u ml18 1 1 20 0 modell w=2u l=2u md19 21 20 0 0 modeld w=10u l=2u ml19 1 1 21 0 modell w=2u l=2u md20 22 21 0 0 modeld w=10u l=2u ml20 1 1 22 0 modell w=2u l=2u md21 23 22 0 0 modeld w=10u l=2u ml21 1 1 23 0 modell w=2u l=2u md22 24 23 0 0 modeld w=10u l=2u ml22 1 1 24 0 modell w=2u l=2u md23 25 24 0 0 modeld w=10u l=2u ml23 1 1 25 0 modell w=2u l=2u md24 26 25 0 0 modeld w=10u l=2u ml24 1 1 26 0 modell w=2u l=2u md25 27 26 0 0 modeld w=10u l=2u ml25 1 1 27 0 modell w=2u l=2u md26 28 27 0 0 modeld w=10u l=2u ml26 1 1 28 0 modell w=2u l=2u md27 29 28 0 0 modeld w=10u l=2u ml27 1 1 29 0 modell w=2u l=2u md28 30 29 0 0 modeld w=10u l=2u ml28 1 1 30 0 modell w=2u l=2u md29 31 30 0 0 modeld w=10u l=2u ml29 1 1 31 0 modell w=2u l=2u md30 32 31 0 0 modeld w=10u l=2u ml30 1 1 32 0 modell w=2u l=2u vdd 1 0 5 vin 2 0 .8 .MODEL MODELD NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5) .MODEL MODELL NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5) .PRINT OP iter(0) V(nodes) .op .end examples/nmosgen.c000066400000000000000000000014511145401216200145030ustar00rootroot00000000000000/* gen.c 03/19/93 * Generate cascased nmos inverters to test simulators */ #include void main(argc,argv) int argc; const char *argv[]; { unsigned count, ii; (void)sscanf(argv[1], "%u", &count); printf("%u cascaded NMOS inverters\n", count); for (ii = 1; ii <= count; ii++){ int jj = ii+1; int kk = jj+1; printf("md%u %u %u %u %u modeld w=10u l=2u\n", ii, kk, jj, 0, 0); printf("ml%u %u %u %u %u modell w=2u l=2u\n", ii, 1, 1, kk, 0); } printf("vdd 1 0 5\n"); printf("vin 2 0 .8\n"); printf(".MODEL MODELD NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5)\n"); printf(".MODEL MODELL NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5)\n"); printf(".PRINT OP iter(0) V(nodes)\n"); printf(".op\n"); printf(".options acct\n"); printf(".end\n"); } examples/nmp100.ckt000066400000000000000000000207471145401216200144200ustar00rootroot00000000000000100 cascaded NMOS inverters vd1 2 0 5 md1 3 1 0 0 modeld w=10u l=2u ml1 2 2 3 0 modell w=2u l=2u vd2 4 0 5 md2 5 3 0 0 modeld w=10u l=2u ml2 4 4 5 0 modell w=2u l=2u vd3 6 0 5 md3 7 5 0 0 modeld w=10u l=2u ml3 6 6 7 0 modell w=2u l=2u vd4 8 0 5 md4 9 7 0 0 modeld w=10u l=2u ml4 8 8 9 0 modell w=2u l=2u vd5 10 0 5 md5 11 9 0 0 modeld w=10u l=2u ml5 10 10 11 0 modell w=2u l=2u vd6 12 0 5 md6 13 11 0 0 modeld w=10u l=2u ml6 12 12 13 0 modell w=2u l=2u vd7 14 0 5 md7 15 13 0 0 modeld w=10u l=2u ml7 14 14 15 0 modell w=2u l=2u vd8 16 0 5 md8 17 15 0 0 modeld w=10u l=2u ml8 16 16 17 0 modell w=2u l=2u vd9 18 0 5 md9 19 17 0 0 modeld w=10u l=2u ml9 18 18 19 0 modell w=2u l=2u vd10 20 0 5 md10 21 19 0 0 modeld w=10u l=2u ml10 20 20 21 0 modell w=2u l=2u vd11 22 0 5 md11 23 21 0 0 modeld w=10u l=2u ml11 22 22 23 0 modell w=2u l=2u vd12 24 0 5 md12 25 23 0 0 modeld w=10u l=2u ml12 24 24 25 0 modell w=2u l=2u vd13 26 0 5 md13 27 25 0 0 modeld w=10u l=2u ml13 26 26 27 0 modell w=2u l=2u vd14 28 0 5 md14 29 27 0 0 modeld w=10u l=2u ml14 28 28 29 0 modell w=2u l=2u vd15 30 0 5 md15 31 29 0 0 modeld w=10u l=2u ml15 30 30 31 0 modell w=2u l=2u vd16 32 0 5 md16 33 31 0 0 modeld w=10u l=2u ml16 32 32 33 0 modell w=2u l=2u vd17 34 0 5 md17 35 33 0 0 modeld w=10u l=2u ml17 34 34 35 0 modell w=2u l=2u vd18 36 0 5 md18 37 35 0 0 modeld w=10u l=2u ml18 36 36 37 0 modell w=2u l=2u vd19 38 0 5 md19 39 37 0 0 modeld w=10u l=2u ml19 38 38 39 0 modell w=2u l=2u vd20 40 0 5 md20 41 39 0 0 modeld w=10u l=2u ml20 40 40 41 0 modell w=2u l=2u vd21 42 0 5 md21 43 41 0 0 modeld w=10u l=2u ml21 42 42 43 0 modell w=2u l=2u vd22 44 0 5 md22 45 43 0 0 modeld w=10u l=2u ml22 44 44 45 0 modell w=2u l=2u vd23 46 0 5 md23 47 45 0 0 modeld w=10u l=2u ml23 46 46 47 0 modell w=2u l=2u vd24 48 0 5 md24 49 47 0 0 modeld w=10u l=2u ml24 48 48 49 0 modell w=2u l=2u vd25 50 0 5 md25 51 49 0 0 modeld w=10u l=2u ml25 50 50 51 0 modell w=2u l=2u vd26 52 0 5 md26 53 51 0 0 modeld w=10u l=2u ml26 52 52 53 0 modell w=2u l=2u vd27 54 0 5 md27 55 53 0 0 modeld w=10u l=2u ml27 54 54 55 0 modell w=2u l=2u vd28 56 0 5 md28 57 55 0 0 modeld w=10u l=2u ml28 56 56 57 0 modell w=2u l=2u vd29 58 0 5 md29 59 57 0 0 modeld w=10u l=2u ml29 58 58 59 0 modell w=2u l=2u vd30 60 0 5 md30 61 59 0 0 modeld w=10u l=2u ml30 60 60 61 0 modell w=2u l=2u vd31 62 0 5 md31 63 61 0 0 modeld w=10u l=2u ml31 62 62 63 0 modell w=2u l=2u vd32 64 0 5 md32 65 63 0 0 modeld w=10u l=2u ml32 64 64 65 0 modell w=2u l=2u vd33 66 0 5 md33 67 65 0 0 modeld w=10u l=2u ml33 66 66 67 0 modell w=2u l=2u vd34 68 0 5 md34 69 67 0 0 modeld w=10u l=2u ml34 68 68 69 0 modell w=2u l=2u vd35 70 0 5 md35 71 69 0 0 modeld w=10u l=2u ml35 70 70 71 0 modell w=2u l=2u vd36 72 0 5 md36 73 71 0 0 modeld w=10u l=2u ml36 72 72 73 0 modell w=2u l=2u vd37 74 0 5 md37 75 73 0 0 modeld w=10u l=2u ml37 74 74 75 0 modell w=2u l=2u vd38 76 0 5 md38 77 75 0 0 modeld w=10u l=2u ml38 76 76 77 0 modell w=2u l=2u vd39 78 0 5 md39 79 77 0 0 modeld w=10u l=2u ml39 78 78 79 0 modell w=2u l=2u vd40 80 0 5 md40 81 79 0 0 modeld w=10u l=2u ml40 80 80 81 0 modell w=2u l=2u vd41 82 0 5 md41 83 81 0 0 modeld w=10u l=2u ml41 82 82 83 0 modell w=2u l=2u vd42 84 0 5 md42 85 83 0 0 modeld w=10u l=2u ml42 84 84 85 0 modell w=2u l=2u vd43 86 0 5 md43 87 85 0 0 modeld w=10u l=2u ml43 86 86 87 0 modell w=2u l=2u vd44 88 0 5 md44 89 87 0 0 modeld w=10u l=2u ml44 88 88 89 0 modell w=2u l=2u vd45 90 0 5 md45 91 89 0 0 modeld w=10u l=2u ml45 90 90 91 0 modell w=2u l=2u vd46 92 0 5 md46 93 91 0 0 modeld w=10u l=2u ml46 92 92 93 0 modell w=2u l=2u vd47 94 0 5 md47 95 93 0 0 modeld w=10u l=2u ml47 94 94 95 0 modell w=2u l=2u vd48 96 0 5 md48 97 95 0 0 modeld w=10u l=2u ml48 96 96 97 0 modell w=2u l=2u vd49 98 0 5 md49 99 97 0 0 modeld w=10u l=2u ml49 98 98 99 0 modell w=2u l=2u vd50 100 0 5 md50 101 99 0 0 modeld w=10u l=2u ml50 100 100 101 0 modell w=2u l=2u vd51 102 0 5 md51 103 101 0 0 modeld w=10u l=2u ml51 102 102 103 0 modell w=2u l=2u vd52 104 0 5 md52 105 103 0 0 modeld w=10u l=2u ml52 104 104 105 0 modell w=2u l=2u vd53 106 0 5 md53 107 105 0 0 modeld w=10u l=2u ml53 106 106 107 0 modell w=2u l=2u vd54 108 0 5 md54 109 107 0 0 modeld w=10u l=2u ml54 108 108 109 0 modell w=2u l=2u vd55 110 0 5 md55 111 109 0 0 modeld w=10u l=2u ml55 110 110 111 0 modell w=2u l=2u vd56 112 0 5 md56 113 111 0 0 modeld w=10u l=2u ml56 112 112 113 0 modell w=2u l=2u vd57 114 0 5 md57 115 113 0 0 modeld w=10u l=2u ml57 114 114 115 0 modell w=2u l=2u vd58 116 0 5 md58 117 115 0 0 modeld w=10u l=2u ml58 116 116 117 0 modell w=2u l=2u vd59 118 0 5 md59 119 117 0 0 modeld w=10u l=2u ml59 118 118 119 0 modell w=2u l=2u vd60 120 0 5 md60 121 119 0 0 modeld w=10u l=2u ml60 120 120 121 0 modell w=2u l=2u vd61 122 0 5 md61 123 121 0 0 modeld w=10u l=2u ml61 122 122 123 0 modell w=2u l=2u vd62 124 0 5 md62 125 123 0 0 modeld w=10u l=2u ml62 124 124 125 0 modell w=2u l=2u vd63 126 0 5 md63 127 125 0 0 modeld w=10u l=2u ml63 126 126 127 0 modell w=2u l=2u vd64 128 0 5 md64 129 127 0 0 modeld w=10u l=2u ml64 128 128 129 0 modell w=2u l=2u vd65 130 0 5 md65 131 129 0 0 modeld w=10u l=2u ml65 130 130 131 0 modell w=2u l=2u vd66 132 0 5 md66 133 131 0 0 modeld w=10u l=2u ml66 132 132 133 0 modell w=2u l=2u vd67 134 0 5 md67 135 133 0 0 modeld w=10u l=2u ml67 134 134 135 0 modell w=2u l=2u vd68 136 0 5 md68 137 135 0 0 modeld w=10u l=2u ml68 136 136 137 0 modell w=2u l=2u vd69 138 0 5 md69 139 137 0 0 modeld w=10u l=2u ml69 138 138 139 0 modell w=2u l=2u vd70 140 0 5 md70 141 139 0 0 modeld w=10u l=2u ml70 140 140 141 0 modell w=2u l=2u vd71 142 0 5 md71 143 141 0 0 modeld w=10u l=2u ml71 142 142 143 0 modell w=2u l=2u vd72 144 0 5 md72 145 143 0 0 modeld w=10u l=2u ml72 144 144 145 0 modell w=2u l=2u vd73 146 0 5 md73 147 145 0 0 modeld w=10u l=2u ml73 146 146 147 0 modell w=2u l=2u vd74 148 0 5 md74 149 147 0 0 modeld w=10u l=2u ml74 148 148 149 0 modell w=2u l=2u vd75 150 0 5 md75 151 149 0 0 modeld w=10u l=2u ml75 150 150 151 0 modell w=2u l=2u vd76 152 0 5 md76 153 151 0 0 modeld w=10u l=2u ml76 152 152 153 0 modell w=2u l=2u vd77 154 0 5 md77 155 153 0 0 modeld w=10u l=2u ml77 154 154 155 0 modell w=2u l=2u vd78 156 0 5 md78 157 155 0 0 modeld w=10u l=2u ml78 156 156 157 0 modell w=2u l=2u vd79 158 0 5 md79 159 157 0 0 modeld w=10u l=2u ml79 158 158 159 0 modell w=2u l=2u vd80 160 0 5 md80 161 159 0 0 modeld w=10u l=2u ml80 160 160 161 0 modell w=2u l=2u vd81 162 0 5 md81 163 161 0 0 modeld w=10u l=2u ml81 162 162 163 0 modell w=2u l=2u vd82 164 0 5 md82 165 163 0 0 modeld w=10u l=2u ml82 164 164 165 0 modell w=2u l=2u vd83 166 0 5 md83 167 165 0 0 modeld w=10u l=2u ml83 166 166 167 0 modell w=2u l=2u vd84 168 0 5 md84 169 167 0 0 modeld w=10u l=2u ml84 168 168 169 0 modell w=2u l=2u vd85 170 0 5 md85 171 169 0 0 modeld w=10u l=2u ml85 170 170 171 0 modell w=2u l=2u vd86 172 0 5 md86 173 171 0 0 modeld w=10u l=2u ml86 172 172 173 0 modell w=2u l=2u vd87 174 0 5 md87 175 173 0 0 modeld w=10u l=2u ml87 174 174 175 0 modell w=2u l=2u vd88 176 0 5 md88 177 175 0 0 modeld w=10u l=2u ml88 176 176 177 0 modell w=2u l=2u vd89 178 0 5 md89 179 177 0 0 modeld w=10u l=2u ml89 178 178 179 0 modell w=2u l=2u vd90 180 0 5 md90 181 179 0 0 modeld w=10u l=2u ml90 180 180 181 0 modell w=2u l=2u vd91 182 0 5 md91 183 181 0 0 modeld w=10u l=2u ml91 182 182 183 0 modell w=2u l=2u vd92 184 0 5 md92 185 183 0 0 modeld w=10u l=2u ml92 184 184 185 0 modell w=2u l=2u vd93 186 0 5 md93 187 185 0 0 modeld w=10u l=2u ml93 186 186 187 0 modell w=2u l=2u vd94 188 0 5 md94 189 187 0 0 modeld w=10u l=2u ml94 188 188 189 0 modell w=2u l=2u vd95 190 0 5 md95 191 189 0 0 modeld w=10u l=2u ml95 190 190 191 0 modell w=2u l=2u vd96 192 0 5 md96 193 191 0 0 modeld w=10u l=2u ml96 192 192 193 0 modell w=2u l=2u vd97 194 0 5 md97 195 193 0 0 modeld w=10u l=2u ml97 194 194 195 0 modell w=2u l=2u vd98 196 0 5 md98 197 195 0 0 modeld w=10u l=2u ml98 196 196 197 0 modell w=2u l=2u vd99 198 0 5 md99 199 197 0 0 modeld w=10u l=2u ml99 198 198 199 0 modell w=2u l=2u vd100 200 0 5 md100 201 199 0 0 modeld w=10u l=2u ml100 200 200 201 0 modell w=2u l=2u vin 1 0 .8 .MODEL MODELD NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5) .MODEL MODELL NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5) .PRINT OP iter(0) V(nodes) .op .end examples/nmpgen.c000066400000000000000000000015271145401216200143250ustar00rootroot00000000000000/* gen.c 03/19/93 * Generate cascased nmos inverters to test simulators */ #include void main(argc,argv) int argc; const char *argv[]; { unsigned count, ii; (void)sscanf(argv[1], "%u", &count); printf("%u cascaded NMOS inverters\n", count); for (ii = 1; ii <= count; ii++){ int in = ii*2-1; int out = ii*2+1; int pwr = ii*2; printf("vd%u %u 0 5\n", ii, pwr); printf("md%u %u %u %u %u modeld w=10u l=2u\n", ii, out, in, 0, 0); printf("ml%u %u %u %u %u modell w=2u l=2u\n", ii, pwr, pwr, out, 0); } printf("vin 1 0 .8\n"); printf(".MODEL MODELD NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5)\n"); printf(".MODEL MODELL NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5)\n"); printf(".PRINT OP iter(0) V(nodes)\n"); printf(".op\n"); printf(".options acct\n"); printf(".end\n"); } examples/opamp-ol.ckt000066400000000000000000000036101145401216200151170ustar00rootroot000000000000002 stage op-amp open loop 02/16/88 * m1 3 2 5 8 cmosn w=5u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 m2 4 1 5 8 cmosn w=5u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 m3 3 3 9 9 cmosp w=5u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 m4 4 3 9 9 cmosp w=5u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 m5 5 7 8 8 cmosn w=5u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 m6 6 4 9 9 cmosp w=9u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 m7 6 7 8 8 cmosn w=5u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 m8 7 7 8 8 cmosn w=5u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 cc 4 6 5.0p ib 9 7 .36u vdd 9 0 2.5 vss 8 0 -2.5 cl 6 0 20p * vin 1 0 dc=0 ac=.5 ein 0 2 1 0 1 * .model cmosn nmos (level=2 ld=0.265073u tox=418.0e-10 + nsub=1.53142e+16 vto=0.844345 kp=4.15964e-05 gamma=0.863074 + phi=0.6 uo=503.521 uexp=0.163917 ucrit=161166 + delta=1e-06 vmax=55903.5 xj=0.400000u lambda=0.01 + nfs=3.5934e+12 neff=1.001 nss=1e+12 tpg=1.000000 + rsh=29.3 cgdo=2.18971e-10 cgso=2.18971e-10 + cj=0.0003844 mj=0.488400 cjsw=5.272e-10 mjsw=0.300200 pb=0.700000) .model cmosp pmos (level=2 ld=0.299878u tox=418.0e-10 + nsub=4.19363e+15 vto=-0.79089 kp=1.64047e-05 gamma=0.451645 + phi=0.6 uo=198.577 uexp=0.343935 ucrit=110988 + delta=0.956806 vmax=41456.3 xj=0.400000u lambda=0.02 + nfs=1e+12 neff=1.001 nss=1e+12 tpg=-1.000000 + rsh=107.6 cgdo=2.47722e-10 cgso=2.47722e-10 + cj=0.0002281 mj=0.508000 cjsw=3.077e-10 mjsw=0.193500 pb=0.740000) * .print op iter(0) v(nodes) .op * .plot ac vdb(6) (0,80) vp(6) (-180,180) .ac dec 5 1 10meg *ac steps start stop * .plot dc v(6) (-4,4) .dc vin -500u 500u 20u *dc start stop stepsize * * Try this in Spice. Compare to the AC analysis above. (same sweep parameters) * It uses the last step in the DC analysis as the bias point. .ac * * Try this in Spice. .plot dc cgs(m7)(5f 7f) .dc *.plot dc cgs(m7)(5f 7f) cgs(m6)(15f 25f) *.dc *.print dc region(m*) *.dc * .end examples/opamp-vf.ckt000066400000000000000000000033301145401216200151170ustar00rootroot000000000000002 stage op-amp, conected as voltage follower 02/16/88 * m1 3 6 5 8 cmosn w=5u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 m2 4 1 5 8 cmosn w=5u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 m3 3 3 9 9 cmosp w=5u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 m4 4 3 9 9 cmosp w=5u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 m5 5 7 8 8 cmosn w=5u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 m6 6 4 9 9 cmosp w=9u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 m7 6 7 8 8 cmosn w=5u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 m8 7 7 8 8 cmosn w=5u l=5u ad=45p as=45p pd=28u ps=28u nrd=1.8 nrs=1.8 cc 4 6 5.0p ib 9 7 .36u vdd 9 0 2.5 vss 8 0 -2.5 cl 6 0 20p * vin 1 0 dc pulse(-1.0 1.0 200u 1u 1u 300u 600u) ac=1 * .model cmosn nmos (level=2 ld=0.265073u tox=418.0e-10 + nsub=1.53142e+16 vto=0.844345 kp=4.15964e-05 gamma=0.863074 + phi=0.6 uo=503.521 uexp=0.163917 ucrit=161166 + delta=1e-06 vmax=55903.5 xj=0.400000u lambda=0.01 + nfs=3.5934e+12 neff=1.001 nss=1e+12 tpg=1.000000 + rsh=29.3 cgdo=2.18971e-10 cgso=2.18971e-10 + cj=0.0003844 mj=0.488400 cjsw=5.272e-10 mjsw=0.300200 pb=0.700000) .model cmosp pmos (level=2 ld=0.299878u tox=418.0e-10 + nsub=4.19363e+15 vto=-0.79089 kp=1.64047e-05 gamma=0.451645 + phi=0.6 uo=198.577 uexp=0.343935 ucrit=110988 + delta=0.956806 vmax=41456.3 xj=0.400000u lambda=0.02 + nfs=1e+12 neff=1.001 nss=1e+12 tpg=-1.000000 + rsh=107.6 cgdo=2.47722e-10 cgso=2.47722e-10 + cj=0.0002281 mj=0.508000 cjsw=3.077e-10 mjsw=0.193500 pb=0.740000) * .print op iter(0) v(nodes) .op * .plot ac vdb(6) (-90,30) vp(6) (-180,180) .ac dec 5 1 10meg *ac steps start stop * .plot dc v(6) (-4,4) .dc vin -5 5 .2 *dc start stop stepsize * .plot tran v(6) (-4,4) .tran 10u 1000u 0 *tran step stop start .end examples/opamp.doc000066400000000000000000000013421145401216200144730ustar00rootroot00000000000000Here are two variations on a CMOS op-amp, similar to the sample 2 stage one in Allen & Holberg's "CMOS Analog Circuit Design" text. It is not an optimal design, just one to play with. The results are the same as Spice, as expected. The files: opamp-ol.ckt open loop: op, ac, dc opamp-vf.ckt voltage follower: op, ac, dc, tran We do a few extras, like a plot of Cgs(M7) vs. input voltage. Try that in Spice. Then, there's another one. An ac analysis at saturation. Try that in Spice. Spice shows you everything, whether you like it or not, on an "op" analysis. You can't see them at all in any other. But those values are not constant. They vary with the signals. ACS will show you (if you want) how they vary with the signal. examples/runall000077500000000000000000000004251145401216200141140ustar00rootroot00000000000000# $1 -b eq2-145.ckt $1 -b eq2-289.ckt $1 -b eq2-577.ckt $1 -b eq3-1153.ckt $1 -b eq4-2305.ckt $1 -b eqboost.ckt $1 -b eqflat.ckt $1 -b eqmodify.ckt $1 -b killzap.ckt $1 -b nmos100.ckt $1 -b nmos18.ckt $1 -b nmos30.ckt $1 -b nmp100.ckt $1 -b opamp-ol.ckt $1 -b opamp-vf.ckt examples/runall.out000066400000000000000000001612351145401216200147260ustar00rootroot00000000000000ACS (Al's Circuit Simulator) 0.2808 Never trust any version less than 1.0 Copyright 1982-2000, Albert Davis ACS comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions according to the GNU General Public License. See the file "COPYING" for details A 145 node circuit # v(2) 1. 0.99847 2. 1.9969 3. 2.9954 4. 3.9939 5. 4.9924 6. 5.9908 7. 6.9893 8. 7.9878 9. 8.9863 10. 9.9847 #Freq vm(2) vdb(2) vp(2) 31.25 0.99847 -0.013271 11.171u 62.5 0.99847 -0.013271 22.349u 125. 0.99847 -0.013271 44.705u 250. 0.99847 -0.013271 89.415u 500. 0.99847 -0.013271 178.83u 1.K 0.99847 -0.01327 357.64u 2.K 0.99847 -0.013269 715.13u 4.K 0.99847 -0.013263 0.001429 8.K 0.99848 -0.013241 0.002848 16.K 0.99849 -0.013154 0.005617 ACS (Al's Circuit Simulator) 0.2808 Never trust any version less than 1.0 Copyright 1982-2000, Albert Davis ACS comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions according to the GNU General Public License. See the file "COPYING" for details A 289 node circuit # v(2) 1. 0.99847 2. 1.9969 3. 2.9954 4. 3.9939 5. 4.9924 6. 5.9908 7. 6.9893 8. 7.9878 9. 8.9863 10. 9.9847 #Freq vm(2) vdb(2) vp(2) 31.25 0.99847 -0.013271 11.171u 62.5 0.99847 -0.013271 22.349u 125. 0.99847 -0.013271 44.705u 250. 0.99847 -0.013271 89.415u 500. 0.99847 -0.013271 178.83u 1.K 0.99847 -0.01327 357.64u 2.K 0.99847 -0.013269 715.13u 4.K 0.99847 -0.013263 0.001429 8.K 0.99848 -0.013241 0.002848 16.K 0.99849 -0.013154 0.005617 ACS (Al's Circuit Simulator) 0.2808 Never trust any version less than 1.0 Copyright 1982-2000, Albert Davis ACS comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions according to the GNU General Public License. See the file "COPYING" for details A 577 node circuit # v(2) 1. 0.99847 2. 1.9969 3. 2.9954 4. 3.9939 5. 4.9924 6. 5.9908 7. 6.9893 8. 7.9878 9. 8.9863 10. 9.9847 #Freq vm(2) vdb(2) vp(2) 31.25 0.99847 -0.013271 11.171u 62.5 0.99847 -0.013271 22.349u 125. 0.99847 -0.013271 44.705u 250. 0.99847 -0.013271 89.415u 500. 0.99847 -0.013271 178.83u 1.K 0.99847 -0.01327 357.64u 2.K 0.99847 -0.013269 715.13u 4.K 0.99847 -0.013263 0.001429 8.K 0.99848 -0.013241 0.002848 16.K 0.99849 -0.013154 0.005617 ACS (Al's Circuit Simulator) 0.2808 Never trust any version less than 1.0 Copyright 1982-2000, Albert Davis ACS comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions according to the GNU General Public License. See the file "COPYING" for details A 1153 node circuit # v(2) 1. 0.98785 2. 1.9757 3. 2.9636 4. 3.9514 5. 4.9393 6. 5.9271 7. 6.915 8. 7.9028 9. 8.8907 10. 9.8785 #Freq vm(2) vdb(2) vp(2) 31.25 0.98785 -0.10617 89.411u 62.5 0.98785 -0.10617 178.83u 125. 0.98785 -0.10617 357.67u 250. 0.98785 -0.10617 715.34u 500. 0.98785 -0.10617 0.0014307 1.K 0.98785 -0.10616 0.0028612 2.K 0.98785 -0.10615 0.0057211 4.K 0.98786 -0.10611 0.011432 8.K 0.98788 -0.10593 0.022784 16.K 0.98796 -0.10523 0.044936 ACS (Al's Circuit Simulator) 0.2808 Never trust any version less than 1.0 Copyright 1982-2000, Albert Davis ACS comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions according to the GNU General Public License. See the file "COPYING" for details A 2305 node circuit # v(2) 1. 0.97585 2. 1.9517 3. 2.9276 4. 3.9034 5. 4.8793 6. 5.8551 7. 6.831 8. 7.8068 9. 8.7827 10. 9.7585 #Freq vm(2) vdb(2) vp(2) 31.25 0.97585 -0.21233 178.83u 62.5 0.97585 -0.21233 357.67u 125. 0.97585 -0.21233 715.34u 250. 0.97585 -0.21233 0.0014307 500. 0.97585 -0.21233 0.0028613 1.K 0.97585 -0.21232 0.0057223 2.K 0.97585 -0.2123 0.011442 4.K 0.97586 -0.21221 0.022864 8.K 0.9759 -0.21186 0.045567 16.K 0.97606 -0.21046 0.089872 ACS (Al's Circuit Simulator) 0.2808 Never trust any version less than 1.0 Copyright 1982-2000, Albert Davis ACS comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions according to the GNU General Public License. See the file "COPYING" for details Graphic equalizer -- boost 1k #Freq vdb(37) vdb(31) vdb(34) 31.25 0.095167 -2.0118n 0.096826 37.163 0.11409 -2.1032n 0.11575 44.194 0.13781 -2.1809n 0.13947 52.556 0.16848 -2.2446n 0.17014 62.5 0.20922 -2.2952n 0.21088 74.325 0.26444 -2.3344n 0.2661 88.388 0.34021 -2.3642n 0.34187 105.11 0.44477 -2.3866n 0.44643 125. 0.58911 -2.4035n 0.59077 148.65 0.78769 -2.4165n 0.78934 176.78 1.059 -2.4266n 1.0607 210.22 1.4262 -2.4349n 1.4279 250. 1.9169 -2.4421n 1.9186 297.3 2.5634 -2.4488n 2.565 353.55 3.4014 -2.4552n 3.403 420.45 4.4697 -2.4615n 4.4714 500. 5.8076 -2.4678n 5.8093 594.6 7.4426 -2.4741n 7.4443 707.11 9.3356 -2.4804n 9.3373 840.9 11.183 -2.4867n 11.184 1.K 12.091 -2.4928n 12.092 1.1892K 11.281 -2.4985n 11.283 1.4142K 9.4491 -2.5039n 9.4508 1.6818K 7.5303 -2.5088n 7.532 2.K 5.8651 -2.5129n 5.8667 2.3784K 4.5032 -2.5158n 4.5049 2.8284K 3.4187 -2.5174n 3.4204 3.3636K 2.5711 -2.5176n 2.5728 4.K 1.9198 -2.5164n 1.9214 4.7568K 1.427 -2.5136n 1.4286 5.6569K 1.0593 -2.5093n 1.061 6.7272K 0.78815 -2.5028n 0.78981 8.K 0.58993 -2.4938n 0.59159 9.5137K 0.44583 -2.4813n 0.44748 11.314K 0.34124 -2.4642n 0.34289 13.454K 0.26508 -2.4413n 0.26673 16.K 0.20907 -2.4112n 0.21072 19.027K 0.16712 -2.3724n 0.16876 22.627K 0.13481 -2.3241n 0.13644 26.909K 0.10904 -2.2657n 0.11066 32.K 0.087701 -2.1976n 0.089304 ACS (Al's Circuit Simulator) 0.2808 Never trust any version less than 1.0 Copyright 1982-2000, Albert Davis ACS comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions according to the GNU General Public License. See the file "COPYING" for details Graphic equalizer -- all bands flat, modify test #Freq vdb(37) vdb(31) vdb(34) 31.25 -0.0033177 -2.1364n -0.0016588 37.163 -0.0033177 -2.2546n -0.0016588 44.194 -0.0033177 -2.3648n -0.0016588 52.556 -0.0033177 -2.4681n -0.0016588 62.5 -0.0033177 -2.5656n -0.0016588 74.325 -0.0033177 -2.6589n -0.0016588 88.388 -0.0033177 -2.7484n -0.0016588 105.11 -0.0033177 -2.8333n -0.0016588 125. -0.0033177 -2.9121n -0.0016588 148.65 -0.0033177 -2.9828n -0.0016588 176.78 -0.0033177 -3.044n -0.0016588 210.22 -0.0033177 -3.0952n -0.0016588 250. -0.0033177 -3.1368n -0.0016588 297.3 -0.0033177 -3.17n -0.0016588 353.55 -0.0033177 -3.1961n -0.0016588 420.45 -0.0033177 -3.2165n -0.0016588 500. -0.0033177 -3.2324n -0.0016588 594.6 -0.0033177 -3.2448n -0.0016588 707.11 -0.0033176 -3.2544n -0.0016588 840.9 -0.0033176 -3.2618n -0.0016588 1.K -0.0033176 -3.2673n -0.0016588 1.1892K -0.0033175 -3.2709n -0.0016588 1.4142K -0.0033175 -3.2725n -0.0016587 1.6818K -0.0033174 -3.2716n -0.0016587 2.K -0.0033172 -3.2674n -0.0016586 2.3784K -0.003317 -3.2592n -0.0016585 2.8284K -0.0033168 -3.2458n -0.0016584 3.3636K -0.0033164 -3.2263n -0.0016582 4.K -0.0033158 -3.1994n -0.0016579 4.7568K -0.0033151 -3.1644n -0.0016575 5.6569K -0.003314 -3.1205n -0.001657 6.7272K -0.0033125 -3.0678n -0.0016562 8.K -0.0033103 -3.0072n -0.0016551 9.5137K -0.0033072 -2.9404n -0.0016536 11.314K -0.003303 -2.8693n -0.0016515 13.454K -0.0032969 -2.7957n -0.0016485 16.K -0.0032885 -2.7202n -0.0016442 19.027K -0.0032767 -2.6425n -0.0016384 22.627K -0.0032603 -2.5619n -0.0016302 26.909K -0.0032378 -2.4772n -0.0016189 32.K -0.003207 -2.388n -0.0016035 ACS (Al's Circuit Simulator) 0.2808 Never trust any version less than 1.0 Copyright 1982-2000, Albert Davis ACS comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions according to the GNU General Public License. See the file "COPYING" for details Graphic equalizer -- all bands flat, modify test #Freq vdb(37) vdb(31) vdb(34) 31.25 -0.0033177 -2.1364n -0.0016588 37.163 -0.0033177 -2.2546n -0.0016588 44.194 -0.0033177 -2.3648n -0.0016588 52.556 -0.0033177 -2.4681n -0.0016588 62.5 -0.0033177 -2.5656n -0.0016588 74.325 -0.0033177 -2.6589n -0.0016588 88.388 -0.0033177 -2.7484n -0.0016588 105.11 -0.0033177 -2.8333n -0.0016588 125. -0.0033177 -2.9121n -0.0016588 148.65 -0.0033177 -2.9828n -0.0016588 176.78 -0.0033177 -3.044n -0.0016588 210.22 -0.0033177 -3.0952n -0.0016588 250. -0.0033177 -3.1368n -0.0016588 297.3 -0.0033177 -3.17n -0.0016588 353.55 -0.0033177 -3.1961n -0.0016588 420.45 -0.0033177 -3.2165n -0.0016588 500. -0.0033177 -3.2324n -0.0016588 594.6 -0.0033177 -3.2448n -0.0016588 707.11 -0.0033176 -3.2544n -0.0016588 840.9 -0.0033176 -3.2618n -0.0016588 1.K -0.0033176 -3.2673n -0.0016588 1.1892K -0.0033175 -3.2709n -0.0016588 1.4142K -0.0033175 -3.2725n -0.0016587 1.6818K -0.0033174 -3.2716n -0.0016587 2.K -0.0033172 -3.2674n -0.0016586 2.3784K -0.003317 -3.2592n -0.0016585 2.8284K -0.0033168 -3.2458n -0.0016584 3.3636K -0.0033164 -3.2263n -0.0016582 4.K -0.0033158 -3.1994n -0.0016579 4.7568K -0.0033151 -3.1644n -0.0016575 5.6569K -0.003314 -3.1205n -0.001657 6.7272K -0.0033125 -3.0678n -0.0016562 8.K -0.0033103 -3.0072n -0.0016551 9.5137K -0.0033072 -2.9404n -0.0016536 11.314K -0.003303 -2.8693n -0.0016515 13.454K -0.0032969 -2.7957n -0.0016485 16.K -0.0032885 -2.7202n -0.0016442 19.027K -0.0032767 -2.6425n -0.0016384 22.627K -0.0032603 -2.5619n -0.0016302 26.909K -0.0032378 -2.4772n -0.0016189 32.K -0.003207 -2.388n -0.0016035 #Freq vdb(37) vdb(31) vdb(34) 31.25 0.095167 -2.0118n 0.096826 37.163 0.11409 -2.1032n 0.11575 44.194 0.13781 -2.1809n 0.13947 52.556 0.16848 -2.2446n 0.17014 62.5 0.20922 -2.2952n 0.21088 74.325 0.26444 -2.3344n 0.2661 88.388 0.34021 -2.3642n 0.34187 105.11 0.44477 -2.3866n 0.44643 125. 0.58911 -2.4035n 0.59077 148.65 0.78769 -2.4165n 0.78934 176.78 1.059 -2.4266n 1.0607 210.22 1.4262 -2.4349n 1.4279 250. 1.9169 -2.4421n 1.9186 297.3 2.5634 -2.4488n 2.565 353.55 3.4014 -2.4552n 3.403 420.45 4.4697 -2.4615n 4.4714 500. 5.8076 -2.4678n 5.8093 594.6 7.4426 -2.4741n 7.4443 707.11 9.3356 -2.4804n 9.3373 840.9 11.183 -2.4867n 11.184 1.K 12.091 -2.4928n 12.092 1.1892K 11.281 -2.4985n 11.283 1.4142K 9.4491 -2.5039n 9.4508 1.6818K 7.5303 -2.5088n 7.532 2.K 5.8651 -2.5129n 5.8667 2.3784K 4.5032 -2.5158n 4.5049 2.8284K 3.4187 -2.5174n 3.4204 3.3636K 2.5711 -2.5176n 2.5728 4.K 1.9198 -2.5164n 1.9214 4.7568K 1.427 -2.5136n 1.4286 5.6569K 1.0593 -2.5093n 1.061 6.7272K 0.78815 -2.5028n 0.78981 8.K 0.58993 -2.4938n 0.59159 9.5137K 0.44583 -2.4813n 0.44748 11.314K 0.34124 -2.4642n 0.34289 13.454K 0.26508 -2.4413n 0.26673 16.K 0.20907 -2.4112n 0.21072 19.027K 0.16712 -2.3724n 0.16876 22.627K 0.13481 -2.3241n 0.13644 26.909K 0.10904 -2.2657n 0.11066 32.K 0.087701 -2.1976n 0.089304 ACS (Al's Circuit Simulator) 0.2808 Never trust any version less than 1.0 Copyright 1982-2000, Albert Davis ACS comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions according to the GNU General Public License. See the file "COPYING" for details ' #Freq vm(2) vdb(2) vp(2) 1.p 1. 54.575p 0. 10.p 1. 545.76p 0. 100.p 1. 5.4576n 0. 1.n 1. 54.576n 0. 10.n 1. 545.76n 0. 100.n 1. 5.4576u 0. 1.u 1. 54.576u 0. 10.u 1.0001 545.77u 0. 100.u 1.0006 0.0054593 0. 0.001 1.0063 0.054748 0. 0.01 1.067 0.56366 0. 0.1 2.6905 8.5967 0. 1. 0.18928 -14.458 -180. 10. 0.016173 -35.824 -180. 100. 0.0015941 -55.95 -180. 1.K 159.18u -75.962 -180. 10.K 15.916u -95.964 -180. 100.K 1.5915u -115.96 -180. 1.Meg 159.15n -135.96 -180. 10.Meg 15.915n -155.96 -180. 100.Meg 1.5915n -175.96 -180. 1.G 159.15p -195.96 -180. #Freq vm(2) vdb(2) vp(2) 0.1 2.6905 8.5967 0. 0.105 2.9389 9.3638 0. 0.11 3.2379 10.205 0. 0.115 3.6046 11.137 0. 0.12 4.0649 12.181 0. 0.125 4.66 13.368 0. 0.13 5.4592 14.743 0. 0.135 6.5893 16.377 0. 0.14 8.3094 18.391 0. 0.145 11.245 21.019 0. 0.15 17.387 24.805 0. 0.155 38.319 31.668 0. 0.16 187.98 45.482 -180. 0.165 27.221 28.698 -180. 0.17 14.673 23.33 -180. 0.175 10.043 20.038 -180. 0.18 7.6345 17.656 -180. 0.185 6.1576 15.788 -180. 0.19 5.1595 14.252 -180. 0.195 4.4398 12.947 -180. 0.2 3.8964 11.813 -180. ACS (Al's Circuit Simulator) 0.2808 Never trust any version less than 1.0 Copyright 1982-2000, Albert Davis ACS comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions according to the GNU General Public License. See the file "COPYING" for details 100 cascaded NMOS inverters # iter(0) V(1) V(2) V(3) V(4) V(5) + V(6) V(7) V(8) V(9) V(10) V(11) V(12) + V(13) V(14) V(15) V(16) V(17) V(18) V(19) + V(20) V(21) V(22) V(23) V(24) V(25) V(26) + V(27) V(28) V(29) V(30) V(31) V(32) V(33) + V(34) V(35) V(36) V(37) V(38) V(39) V(40) + V(41) V(42) V(43) V(44) V(45) V(46) V(47) + V(48) V(49) V(50) V(51) V(52) V(53) V(54) + V(55) V(56) V(57) V(58) V(59) V(60) V(61) + V(62) V(63) V(64) V(65) V(66) V(67) V(68) + V(69) V(70) V(71) V(72) V(73) V(74) V(75) + V(76) V(77) V(78) V(79) V(80) V(81) V(82) + V(83) V(84) V(85) V(86) V(87) V(88) V(89) + V(90) V(91) V(92) V(93) V(94) V(95) V(96) + V(97) V(98) V(99) V(100) V(101) V(102) 300.15 32. 5. 0.8 3.0455 0.49727 3.2034 + 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 + 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 + 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 + 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 + 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 + 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 + 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 + 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 + 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 + 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 + 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 + 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 + 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 + 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 ACS (Al's Circuit Simulator) 0.2808 Never trust any version less than 1.0 Copyright 1982-2000, Albert Davis ACS comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions according to the GNU General Public License. See the file "COPYING" for details 18 cascaded NMOS inverters # iter(0) V(1) V(2) V(3) V(4) V(5) + V(6) V(7) V(8) V(9) V(10) V(11) V(12) + V(13) V(14) V(15) V(16) V(17) V(18) V(19) + V(20) 300.15 24. 5. 0.8 3.0455 0.49727 3.2034 + 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 + 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 + 0.46622 ACS (Al's Circuit Simulator) 0.2808 Never trust any version less than 1.0 Copyright 1982-2000, Albert Davis ACS comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions according to the GNU General Public License. See the file "COPYING" for details 30 cascaded NMOS inverters # iter(0) V(1) V(2) V(3) V(4) V(5) + V(6) V(7) V(8) V(9) V(10) V(11) V(12) + V(13) V(14) V(15) V(16) V(17) V(18) V(19) + V(20) V(21) V(22) V(23) V(24) V(25) V(26) + V(27) V(28) V(29) V(30) V(31) V(32) 300.15 45. 5. 0.8 3.0455 0.49727 3.2034 + 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 + 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 + 0.46622 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 + 3.2034 0.46622 3.2034 0.46622 3.2034 0.46622 ACS (Al's Circuit Simulator) 0.2808 Never trust any version less than 1.0 Copyright 1982-2000, Albert Davis ACS comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions according to the GNU General Public License. See the file "COPYING" for details 100 cascaded NMOS inverters # iter(0) V(1) V(2) V(3) V(4) V(5) + V(6) V(7) V(8) V(9) V(10) V(11) V(12) + V(13) V(14) V(15) V(16) V(17) V(18) V(19) + V(20) V(21) V(22) V(23) V(24) V(25) V(26) + V(27) V(28) V(29) V(30) V(31) V(32) V(33) + V(34) V(35) V(36) V(37) V(38) V(39) V(40) + V(41) V(42) V(43) V(44) V(45) V(46) V(47) + V(48) V(49) V(50) V(51) V(52) V(53) V(54) + V(55) V(56) V(57) V(58) V(59) V(60) V(61) + V(62) V(63) V(64) V(65) V(66) V(67) V(68) + V(69) V(70) V(71) V(72) V(73) V(74) V(75) + V(76) V(77) V(78) V(79) V(80) V(81) V(82) + V(83) V(84) V(85) V(86) V(87) V(88) V(89) + V(90) V(91) V(92) V(93) V(94) V(95) V(96) + V(97) V(98) V(99) V(100) V(101) V(102) V(103) + V(104) V(105) V(106) V(107) V(108) V(109) V(110) + V(111) V(112) V(113) V(114) V(115) V(116) V(117) + V(118) V(119) V(120) V(121) V(122) V(123) V(124) + V(125) V(126) V(127) V(128) V(129) V(130) V(131) + V(132) V(133) V(134) V(135) V(136) V(137) V(138) + V(139) V(140) V(141) V(142) V(143) V(144) V(145) + V(146) V(147) V(148) V(149) V(150) V(151) V(152) + V(153) V(154) V(155) V(156) V(157) V(158) V(159) + V(160) V(161) V(162) V(163) V(164) V(165) V(166) + V(167) V(168) V(169) V(170) V(171) V(172) V(173) + V(174) V(175) V(176) V(177) V(178) V(179) V(180) + V(181) V(182) V(183) V(184) V(185) V(186) V(187) + V(188) V(189) V(190) V(191) V(192) V(193) V(194) + V(195) V(196) V(197) V(198) V(199) V(200) V(201) 300.15 24. 0.8 5. 3.0455 5. 0.49727 + 5. 3.2034 5. 0.46622 5. 3.2034 5. + 0.46622 5. 3.2034 5. 0.46622 5. 3.2034 + 5. 0.46622 5. 3.2034 5. 0.46622 5. + 3.2034 5. 0.46622 5. 3.2034 5. 0.46622 + 5. 3.2034 5. 0.46622 5. 3.2034 5. + 0.46622 5. 3.2034 5. 0.46622 5. 3.2034 + 5. 0.46622 5. 3.2034 5. 0.46622 5. + 3.2034 5. 0.46622 5. 3.2034 5. 0.46622 + 5. 3.2034 5. 0.46622 5. 3.2034 5. + 0.46622 5. 3.2034 5. 0.46622 5. 3.2034 + 5. 0.46622 5. 3.2034 5. 0.46622 5. + 3.2034 5. 0.46622 5. 3.2034 5. 0.46622 + 5. 3.2034 5. 0.46622 5. 3.2034 5. + 0.46622 5. 3.2034 5. 0.46622 5. 3.2034 + 5. 0.46622 5. 3.2034 5. 0.46622 5. + 3.2034 5. 0.46622 5. 3.2034 5. 0.46622 + 5. 3.2034 5. 0.46622 5. 3.2034 5. + 0.46622 5. 3.2034 5. 0.46622 5. 3.2034 + 5. 0.46622 5. 3.2034 5. 0.46622 5. + 3.2034 5. 0.46622 5. 3.2034 5. 0.46622 + 5. 3.2034 5. 0.46622 5. 3.2034 5. + 0.46622 5. 3.2034 5. 0.46622 5. 3.2034 + 5. 0.46622 5. 3.2034 5. 0.46622 5. + 3.2034 5. 0.46622 5. 3.2034 5. 0.46622 + 5. 3.2034 5. 0.46622 5. 3.2034 5. + 0.46622 5. 3.2034 5. 0.46622 5. 3.2034 + 5. 0.46622 5. 3.2034 5. 0.46622 5. + 3.2034 5. 0.46622 5. 3.2034 5. 0.46622 ACS (Al's Circuit Simulator) 0.2808 Never trust any version less than 1.0 Copyright 1982-2000, Albert Davis ACS comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions according to the GNU General Public License. See the file "COPYING" for details 2 stage op-amp open loop 02/16/88 # iter(0) v(1) v(2) v(3) v(4) v(5) + v(6) v(7) v(8) v(9) 300.15 18. 0. 0. 0.87501 0.87512 -1.1707 +-0.23876 -1.6303 -2.5 2.5 vdb(6) 0. 20. 40. 60. 80. vp(6)-180. -90. 0. 90. 180. +-----------------+----------------+-----------------+----------------+ 1. | . +. . * | 1.5849 | . + . . * | 2.5119 | . + . . * | 3.9811 | . + . . * | 6.3096 | . + . . * | 10. | . + . . * | 15.849 | . + . . * | 25.119 | . + . * | 39.811 | . + . * . | 63.096 | .+ . * . | 100. | + . * . | 158.49 | + . * . | 251.19 | + .* . | 398.11 | + * . . | 630.96 | +. * . . | 1.K | +. * . . | 1.5849K| +. * . . | 2.5119K| +* . . | 3.9811K| *+ . . . | 6.3096K| * + . . . | 10.K | * + . . . | 15.849K| * + . . . | 25.119K* + . . . | 39.811K* + . . . | 63.096K*+ . . . | 100.K * . . . + | 158.49K* . . . + | 251.19K* . . . + | 398.11K* . . . + | 630.96K* . . . + | 1.Meg * . . .+ | 1.5849M* . . +. | 2.5119M* . . + . | 3.9811M* . . + . | 6.3096M* . . + . | 10.Meg * . . + . | +-----------------+----------------+-----------------+----------------+ v(6) -4. -2. 0. 2. 4. +-----------------+----------------+-----------------+----------------+ -500.u | * . . . | -480.u | * . . . | -460.u | * . . . | -440.u | * . . . | -420.u | * . . . | -400.u | * . . . | -380.u | * . . . | -360.u | * . . . | -340.u | * . . . | -320.u | * . . . | -300.u | * . . . | -280.u | * . . . | -260.u | * . . . | -240.u | * . . . | -220.u | * . . . | -200.u | * . . . | -180.u | * . . . | -160.u | * . . . | -140.u | * . . . | -120.u | *. . . | -100.u | . * . . | -80.u | . * . . | -60.u | . * . . | -40.u | . * . . | -20.u | . * . . | 0. | . * . . | 20.u | . * . | 40.u | . . * . | 60.u | . . * . | 80.u | . . * . | 100.u | . . * . | 120.u | . . * . | 140.u | . . * . | 160.u | . . * . | 180.u | . . * | 200.u | . . .* | 220.u | . . . * | 240.u | . . . * | 260.u | . . . * | 280.u | . . . * | 300.u | . . . * | 320.u | . . . * | 340.u | . . . * | 360.u | . . . * | 380.u | . . . * | 400.u | . . . * | 420.u | . . . * | 440.u | . . . * | 460.u | . . . * | 480.u | . . . * | 500.u | . . . * | +-----------------+----------------+-----------------+----------------+ vdb(6) 0. 20. 40. 60. 80. vp(6)-180. -90. 0. 90. 180. +-----------------+----------------+-----------------+----------------+ 1. | . * + . | 1.5849 | . * + . | 2.5119 | . * + . | 3.9811 | . * + . | 6.3096 | . * + . | 10. | . * + . | 15.849 | . * + . | 25.119 | . * +. . | 39.811 | . * +. . | 63.096 | . * + . . | 100. | . * + . . | 158.49 | . * + . . | 251.19 | . * + . . | 398.11 | . * + . . | 630.96 | . * + . . | 1.K | * + . . | 1.5849K| * . + . . | 2.5119K| * .+ . . | 3.9811K| * +. . . | 6.3096K| * + . . . | 10.K |* + . . . | 15.849K* + . . . | 25.119K* + . . . | 39.811K* + . . . | 63.096K* . . . | 100.K * . . . + | 158.49K* . . . + | 251.19K* . . . + | 398.11K* . . . + | 630.96K* . . .+ | 1.Meg * . . + | 1.5849M* . . +. | 2.5119M* . . + . | 3.9811M* . . + . | 6.3096M* . . + . | 10.Meg * . . + . | +-----------------+----------------+-----------------+----------------+ cgs(M7) 5.f 5.5f 6.f 6.5f 7.f +-----------------+----------------+-----------------+----------------+ -500.u | * . . | -480.u | .* . . | -460.u | . * . . | -440.u | . * . . | -420.u | . * . . | -400.u | . * . . | -380.u | . * . . | -360.u | . * . . | -340.u | . * . . | -320.u | . * . . | -300.u | . * . . | -280.u | . * . . | -260.u | . .* . | -240.u | . . * . | -220.u | . . * . | -200.u | . . * . | -180.u | . . * . | -160.u | . . * . | -140.u | . . *. | -120.u | . . .* | -100.u | . . . * | -80.u | . . . * | -60.u | . . . * | -40.u | . . . * | -20.u | . . . * | 0. | . . . * | 20.u | . . . * | 40.u | . . . * | 60.u | . . . * | 80.u | . . . * | 100.u | . . . * | 120.u | . . . * | 140.u | . . . * | 160.u | . . . *| 180.u | . . . *| 200.u | . . . * 220.u | . . . * 240.u | . . . * 260.u | . . . * 280.u | . . . * 300.u | . . . * 320.u | . . . * 340.u | . . . * 360.u | . . . * 380.u | . . . * 400.u | . . . * 420.u | . . . * 440.u | . . . * 460.u | . . . * 480.u | . . . * 500.u | . . . * +-----------------+----------------+-----------------+----------------+ ACS (Al's Circuit Simulator) 0.2808 Never trust any version less than 1.0 Copyright 1982-2000, Albert Davis ACS comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions according to the GNU General Public License. See the file "COPYING" for details 2 stage op-amp, conected as voltage follower 02/16/88 # iter(0) v(1) v(3) v(4) v(5) v(6) + v(7) v(8) v(9) 300.15 20. -1. 0.87713 0.88005 -1.9308 -0.99992 +-1.6303 -2.5 2.5 vdb(6)-90. -60. -30. 0. 30. vp(6)-180. -90. 0. 90. 180. +-----------------+----------------+-----------------+----------------+ 1. | . + *. | 1.5849 | . + *. | 2.5119 | . + *. | 3.9811 | . + *. | 6.3096 | . + *. | 10. | . + *. | 15.849 | . + *. | 25.119 | . + *. | 39.811 | . + *. | 63.096 | . + *. | 100. | . + *. | 158.49 | . + *. | 251.19 | . + *. | 398.11 | . + *. | 630.96 | . + * | 1.K | . + * | 1.5849K| . +. * | 2.5119K| . +. * | 3.9811K| . + . * | 6.3096K| . + . * | 10.K | . + . * | 15.849K| . + . * | 25.119K| . + . * | 39.811K| + . . * . | 63.096K| + . . * . | 100.K | . . * . + | 158.49K| . . * . + | 251.19K| . * . + | 398.11K| . * . . + | 630.96K| . * . . + | 1.Meg | . * . .+ | 1.5849M| . * . +. | 2.5119M| . * . +. | 3.9811M| .* . +. | 6.3096M| *. . +. | 10.Meg | * . . + | +-----------------+----------------+-----------------+----------------+ v(6) -4. -2. 0. 2. 4. +-----------------+----------------+-----------------+----------------+ -5. | * . . . | -4.8 | * . . . | -4.6 | * . . . | -4.4 | * . . . | -4.2 | * . . . | -4. | * . . . | -3.8 | * . . . | -3.6 | * . . . | -3.4 | * . . . | -3.2 | * . . . | -3. | * . . . | -2.8 | * . . . | -2.6 | * . . . | -2.4 | * . . . | -2.2 | * . . . | -2. | *. . . | -1.8 | .* . . | -1.6 | . * . . | -1.4 | . * . . | -1.2 | . * . . | -1. | . * . . | -0.8 | . * . . | -0.6 | . * . . | -0.4 | . * . . | -0.2 | . * . . | 0. | . * . | 0.2 | . . * . | 0.4 | . . * . | 0.6 | . . * . | 0.8 | . . * . | 1. | . . * . | 1.2 | . . * . | 1.4 | . . * . | 1.6 | . . * . | 1.8 | . . * . | 2. | . . *. | 2.2 | . . .* | 2.4 | . . . * | 2.6 | . . . * | 2.8 | . . . * | 3. | . . . * | 3.2 | . . . * | 3.4 | . . . * | 3.6 | . . . * | 3.8 | . . . * | 4. | . . . * | 4.2 | . . . * | 4.4 | . . . * | 4.6 | . . . * | 4.8 | . . . * | 5. | . . . * | +-----------------+----------------+-----------------+----------------+ v(6) -4. -2. 0. 2. 4. +-----------------+----------------+-----------------+----------------+ 0. | . * . . | 10.u | . * . . | 20.u | . * . . | 30.u | . * . . | 40.u | . * . . | 50.u | . * . . | 60.u | . * . . | 70.u | . * . . | 80.u | . * . . | 90.u | . * . . | 100.u | . * . . | 110.u | . * . . | 120.u | . * . . | 130.u | . * . . | 140.u | . * . . | 150.u | . * . . | 160.u | . * . . | 170.u | . * . . | 180.u | . * . . | 190.u | . * . . | 200.u | . * . . | 210.u | . * . . | 220.u | . *. . | 230.u | . . * . | 240.u | . . * . | 250.u | . . * . | 260.u | . . * . | 270.u | . . * . | 280.u | . . * . | 290.u | . . * . | 300.u | . . * . | 310.u | . . * . | 320.u | . . * . | 330.u | . . * . | 340.u | . . * . | 350.u | . . * . | 360.u | . . * . | 370.u | . . * . | 380.u | . . * . | 390.u | . . * . | 400.u | . . * . | 410.u | . . * . | 420.u | . . * . | 430.u | . . * . | 440.u | . . * . | 450.u | . . * . | 460.u | . . * . | 470.u | . . * . | 480.u | . . * . | 490.u | . . * . | 500.u | . . * . | 510.u | . . * . | 520.u | . . * . | 530.u | . . * . | 540.u | . . * . | 550.u | . . * . | 560.u | . . * . | 570.u | . . * . | 580.u | . .* . | 590.u | . * . | 600.u | . *. . | 610.u | . * . . | 620.u | . * . . | 630.u | . * . . | 640.u | . * . . | 650.u | . * . . | 660.u | . * . . | 670.u | . * . . | 680.u | . * . . | 690.u | . * . . | 700.u | . * . . | 710.u | . * . . | 720.u | . * . . | 730.u | . * . . | 740.u | . * . . | 750.u | . * . . | 760.u | . * . . | 770.u | . * . . | 780.u | . * . . | 790.u | . * . . | 800.u | . * . . | 810.u | . * . . | 820.u | . *. . | 830.u | . . * . | 840.u | . . * . | 850.u | . . * . | 860.u | . . * . | 870.u | . . * . | 880.u | . . * . | 890.u | . . * . | 900.u | . . * . | 910.u | . . * . | 920.u | . . * . | 930.u | . . * . | 940.u | . . * . | 950.u | . . * . | 960.u | . . * . | 970.u | . . * . | 980.u | . . * . | 990.u | . . * . | 0.001 | . . * . | +-----------------+----------------+-----------------+----------------+ examples/sc18.ckt000066400000000000000000000026321145401216200141540ustar00rootroot0000000000000018 cascaded NMOS inverters md1 3 2 0 0 modeld w=10u l=2u ml1 1 1 3 0 modell w=2u l=2u md2 4 3 0 0 modeld w=10u l=2u ml2 1 1 4 0 modell w=2u l=2u md3 5 4 0 0 modeld w=10u l=2u ml3 1 1 5 0 modell w=2u l=2u md4 6 5 0 0 modeld w=10u l=2u ml4 1 1 6 0 modell w=2u l=2u md5 7 6 0 0 modeld w=10u l=2u ml5 1 1 7 0 modell w=2u l=2u md6 8 7 0 0 modeld w=10u l=2u ml6 1 1 8 0 modell w=2u l=2u md7 9 8 0 0 modeld w=10u l=2u ml7 1 1 9 0 modell w=2u l=2u md8 10 9 0 0 modeld w=10u l=2u ml8 1 1 10 0 modell w=2u l=2u md9 11 10 0 0 modeld w=10u l=2u ml9 1 1 11 0 modell w=2u l=2u md10 12 11 0 0 modeld w=10u l=2u ml10 1 1 12 0 modell w=2u l=2u md11 13 12 0 0 modeld w=10u l=2u ml11 1 1 13 0 modell w=2u l=2u md12 14 13 0 0 modeld w=10u l=2u ml12 1 1 14 0 modell w=2u l=2u md13 15 14 0 0 modeld w=10u l=2u ml13 1 1 15 0 modell w=2u l=2u md14 16 15 0 0 modeld w=10u l=2u ml14 1 1 16 0 modell w=2u l=2u md15 17 16 0 0 modeld w=10u l=2u ml15 1 1 17 0 modell w=2u l=2u md16 18 17 0 0 modeld w=10u l=2u ml16 1 1 18 0 modell w=2u l=2u md17 19 18 0 0 modeld w=10u l=2u ml17 1 1 19 0 modell w=2u l=2u md18 20 19 0 0 modeld w=10u l=2u ml18 1 1 20 0 modell w=2u l=2u vdd 1 0 5 vin 2 0 .8 .MODEL MODELD NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5 nfs=1e12) .MODEL MODELL NMOS (level=2 KP=28U VTO=0.7 LAMBDA=0.01 GAMMA=0.9 PHI=0.5 nfs=1e12) .PRINT OP iter(0) V(nodes) .op .end install-sh000077500000000000000000000220211145401216200130530ustar00rootroot00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2005-05-14.22 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" chmodcmd="$chmodprog 0755" chowncmd= chgrpcmd= stripcmd= rmcmd="$rmprog -f" mvcmd="$mvprog" src= dst= dir_arg= dstarg= no_target_directory= usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: -c (ignored) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. --help display this help and exit. --version display version info and exit. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test -n "$1"; do case $1 in -c) shift continue;; -d) dir_arg=true shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; --help) echo "$usage"; exit $?;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t) dstarg=$2 shift shift continue;; -T) no_target_directory=true shift continue;; --version) echo "$0 $scriptversion"; exit $?;; *) # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. test -n "$dir_arg$dstarg" && break # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dstarg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dstarg" shift # fnord fi shift # arg dstarg=$arg done break;; esac done if test -z "$1"; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi for src do # Protect names starting with `-'. case $src in -*) src=./$src ;; esac if test -n "$dir_arg"; then dst=$src src= if test -d "$dst"; then mkdircmd=: chmodcmd= else mkdircmd=$mkdirprog fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dstarg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dstarg # Protect names starting with `-'. case $dst in -*) dst=./$dst ;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dstarg: Is a directory" >&2 exit 1 fi dst=$dst/`basename "$src"` fi fi # This sed command emulates the dirname command. dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` # Make sure that the destination directory exists. # Skip lots of stat calls in the usual case. if test ! -d "$dstdir"; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` shift IFS=$oIFS pathcomp= while test $# -ne 0 ; do pathcomp=$pathcomp$1 shift if test ! -d "$pathcomp"; then $mkdirprog "$pathcomp" # mkdir can fail with a `File exist' error in case several # install-sh are creating the directory concurrently. This # is OK. test -d "$pathcomp" || exit fi pathcomp=$pathcomp/ done fi if test -n "$dir_arg"; then $doit $mkdircmd "$dst" \ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } else dstfile=`basename "$dst"` # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 trap '(exit $?); exit' 1 2 13 15 # Copy the file name to the temp name. $doit $cpprog "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && # Now rename the file to the real destination. { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ || { # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { if test -f "$dstdir/$dstfile"; then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit 1 } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" } } fi || { (exit 1); exit 1; } done # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit 0 } # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: missing000077500000000000000000000254061145401216200124600ustar00rootroot00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2005-06-08.21 # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). case "$1" in lex|yacc) # Not GNU programs, they don't have --version. ;; tar) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; tar) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: modelgen/000077500000000000000000000000001145401216200126445ustar00rootroot00000000000000modelgen/Make.depend000066400000000000000000000025561145401216200147120ustar00rootroot00000000000000mg_main.o: mg_main.cc u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h mg_out.h mg_.h ap.h patchlev.h mg_error.o: mg_error.cc ap.h md.h io_trace.h io_error.h mg_in.o: mg_in.cc mg_.h md.h io_trace.h io_error.h ap.h mg_out_h.o: mg_out_h.cc mg_out.h mg_.h md.h io_trace.h io_error.h ap.h mg_out_dump.o: mg_out_dump.cc md.h io_trace.h io_error.h mg_out.h mg_.h \ ap.h mg_out_common.o: mg_out_common.cc mg_out.h mg_.h md.h io_trace.h \ io_error.h ap.h mg_out_dev.o: mg_out_dev.cc mg_out.h mg_.h md.h io_trace.h io_error.h \ ap.h mg_out_lib.o: mg_out_lib.cc mg_out.h mg_.h md.h io_trace.h io_error.h \ ap.h mg_out_model.o: mg_out_model.cc mg_out.h mg_.h md.h io_trace.h io_error.h \ ap.h mg_out_root.o: mg_out_root.cc md.h io_trace.h io_error.h mg_out.h mg_.h \ ap.h ap_construct.o: ap_construct.cc u_opt.h mode.h io_.h l_lib.h md.h \ io_trace.h io_error.h ap.h ap_convert.o: ap_convert.cc u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h ap.h ap_get.o: ap_get.cc ap.h md.h io_trace.h io_error.h ap_match.o: ap_match.cc u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h ap.h ap_skip.o: ap_skip.cc ap.h md.h io_trace.h io_error.h l_trim.o: l_trim.cc u_opt1.o: u_opt1.cc u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h io_out.o: io_out.cc u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h io.o: io.cc io_.h l_lib.h md.h io_trace.h io_error.h modelgen/Make1000066400000000000000000000067141145401216200135350ustar00rootroot00000000000000#$Id: Make1,v 26.81 2008/05/27 05:33:43 al Exp $ -*- Makefile -*- # # Copyright (C) 2001 Albert Davis # Author: Albert Davis # # This file is part of "Gnucap", the Gnu Circuit Analysis Package # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. #------------------------------------------------------------------------ TARGET = gnucap-modelgen #------------------------------------------------------------------------ DELETED = #------------------------------------------------------------------------ #------------------------------------------------------------------------ RAW_SRCS = \ mg_main.cc mg_error.cc mg_in.cc mg_out_h.cc mg_out_dump.cc \ mg_out_common.cc mg_out_dev.cc mg_out_lib.cc mg_out_model.cc mg_out_root.cc #------------------------------------------------------------------------ RAW_HDRS = mg_.h mg_out.h declare.h #------------------------------------------------------------------------ RAW_OTHER = \ configure.old Make1 \ Makefile.am #------------------------------------------------------------------------ RAW = $(RAW_HDRS) $(RAW_SRCS) $(RAW_OTHER) #------------------------------------------------------------------------ #------------------------------------------------------------------------ IMPORTED_SRCS = \ ap_construct.cc ap_convert.cc ap_get.cc ap_match.cc ap_skip.cc \ l_trim.cc u_opt1.cc io_out.cc io.cc IMPORTED_HDRS = \ ap.h io_.h io_error.h io_trace.h l_lib.h md.h patchlev.h u_opt.h mode.h IMPORTED_OTHER = Makefile.in \ Make2.g++ Make2.Debug Make2.mingw32 Make3 Makefile.template IMPORTED = $(IMPORTED_SRCS) $(IMPORTED_HDRS) $(IMPORTED_OTHER) #------------------------------------------------------------------------ #------------------------------------------------------------------------ GENERATED_SRCS = GENERATED_HDRS = GENERATED_OTHER = Make.aux GENERATED = $(GENERATED_HDRS) $(GENERATED_SRCS) $(GENERATED_OTHER) #------------------------------------------------------------------------ #------------------------------------------------------------------------ GENERATED_DIST = Make.depend IMPORTED_DIST = $(IMPORTED) DISTFILES = $(RAW) $(GENERATED_DIST) $(IMPORTED_DIST) #------------------------------------------------------------------------ #------------------------------------------------------------------------ SRCS = $(RAW_SRCS) $(GENERATED_SRCS) $(IMPORTED_SRCS) HDRS = $(RAW_HDRS) $(GENERATED_HDRS) $(IMPORTED_HDRS) OBJS = ${SRCS:.cc=.o} TARGET_DEPENDS = $(OBJS) $(RAW) #------------------------------------------------------------------------ #------------------------------------------------------------------------ MOSTLYCLEANFILES = $(OBJS) $(GENERATED) CLEANFILES = $(MOSTLYCLEANFILES) DISTCLEANFILES = $(CLEANFILES) MAINTAINERCLEANFILES = $(DISTCLEANFILES) #------------------------------------------------------------------------ #------------------------------------------------------------------------ modelgen/Make2.Debug000066400000000000000000000072221145401216200145560ustar00rootroot00000000000000#$Id: Make2.Debug,v 26.97 2008/10/11 03:13:53 al Exp $ -*- Makefile -*- # Copyright (C) 2001 Albert Davis # Author: Albert Davis # # This file is part of "Gnucap", the Gnu Circuit Analysis Package # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. #------------------------------------------------------------------------ VPATH = .:.. # Standard base for g++, debugging, a little optimization # Running the program will give a spew of line markers for debugging. CCC = g++ CCFLAGS = \ -DHAVE_LIBREADLINE \ -DUNIX -g -O0 -I. -I.. -DTRACE_UNTESTED \ -Wall -Wextra \ -Wswitch-enum -Wundef -Wpointer-arith -Woverloaded-virtual \ -Wcast-qual -Wcast-align -Wpacked -Wshadow -Wconversion \ -Winit-self -Wmissing-include-dirs -Winvalid-pch \ -Wvolatile-register-var -Wstack-protector \ -Wlogical-op -Wvla -Woverlength-strings -Wsign-conversion #last line not in 4.1 LIBS = \ -lreadline -ltermcap \ LDFLAGS = -rdynamic %.SUFFIXES: .SUFFIXES: .o .cc .cc.o:; $(CCC) $(CCFLAGS) -c $< #------------------------------------------------------------------------ $(TARGET): $(TARGET_DEPENDS) rm -f $@ $(CCC) $(CCFLAGS) $(OBJS) $(LIBS) $(LDFLAGS) -o $@ #------------------------------------------------------------ # warnings turned off, because they warn of nothing wrong # 4.3 #-Wswitch-default -- lack of default is correct with enum #-Wfloat-equal -- warns on NA, div by zero trap #-Wpadded -- a bool in a class is enough #-Wredundant-decls -- in both header and func is an error check #-Wmissing-declarations -- pascal style #-Wmissing-noreturn -- warns when always throws exception #-Wunreachable-code -- warns even if reachable .. compiler bug?? #-Waggregate-return -- warns even if passed by reference #-Wunsafe-loop-optimizations -- if can't unroll a loop #-Winline #-Wdisabled-optimization -- -O0 disables optimization, so it warns # 4.2 #-Wpadded -- a bool in a class is enough #-Winline #-Waggregate-return -- warns even if passed by reference #-Wfloat-equal -- warns on NA, div by zero trap #-Wredundant-decls -- in both header and func is an error check #-Wunsafe-loop-optimizations -- warns on any loop with variable count # warnings turned off, because of the public headers #-Wunreachable-code -- didn't use nonportable syntax to hide #-Wmissing-noreturn -- didn't use nonportable syntax to hide # warnings that should be on, but ... #-Wshadow -- lambda functions #------------------------------------------------------------ # If you are porting and using g++, you should use this file as a start, # for a "debug" version, with extra warnings and run-time tracing. # If you get errors or warnings, make a copy of it and modify that. # After it works, use the file "Make2.g++" as a start for # executable to use. # If the port is non-trivial, check with me first because someone else # may have already done it. # If it works without changes, send me a note so I can put it in the docs. # Please send the changes to aldavis@gnu.org #------------------------------------------------------------ #------------------------------------------------------------ modelgen/Make2.g++000066400000000000000000000042261145401216200141050ustar00rootroot00000000000000#$Id: Make2.g++,v 26.134 2009/11/29 03:47:06 al Exp $ -*- Makefile -*- # Copyright (C) 2001 Albert Davis # Author: Albert Davis # # This file is part of "Gnucap", the Gnu Circuit Analysis Package # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. #------------------------------------------------------------------------ VPATH = .:.. # Standard base for g++. CCC = g++ CCFLAGS = \ -DHAVE_LIBREADLINE \ -DUNIX -O3 -DNDEBUG -I.. -I. -W LIBS = \ -lreadline -ltermcap \ LDFLAGS = -rdynamic .SUFFIXES: .SUFFIXES: .o .cc .cc.o:; $(CCC) $(CCFLAGS) -c $< #------------------------------------------------------------------------ $(TARGET): $(TARGET_DEPENDS) rm -f $@ $(CCC) $(CCFLAGS) $(OBJS) $(LIBS) $(LDFLAGS) -o $@ #------------------------------------------------------------ # If you are porting and using g++, you should use this file as a start, # for a "release" version, optimized with run-time tracing removed. # If you get errors or warnings, make a copy of it and modify that. # For the first cut, use "Make2.Debug" as the start for more tracing, # or "Make2.Trace" for an extreme amount of tracing. # After it works, use the file "Make2.g++" as a start for # executable to use. # If the port is non-trivial, check with me first because someone else # may have already done it. # If it works without changes, send me a note so I can put it in the docs. # Please send the changes to aldavis@gnu.org #------------------------------------------------------------ #------------------------------------------------------------ modelgen/Make2.mingw32000066400000000000000000000046721145401216200150240ustar00rootroot00000000000000#$Id: Make2.mingw32,v 26.81 2008/05/27 05:34:00 al Exp $ -*- Makefile -*- # Copyright (C) 2001 Albert Davis # Author: Albert Davis # # This file is part of "Gnucap", the Gnu Circuit Analysis Package # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. #------------------------------------------------------------------------ VPATH = .:.. # Standard base for g++. CCC = i586-mingw32msvc-g++ DLLTOOL = i586-mingw32msvc-dlltool CCFLAGS = \ -O2 -DNDEBUG -I.. -I. LIBS = \ LDFLAGS = .SUFFIXES: .SUFFIXES: .o .cc .cc.o:; $(CCC) $(CCFLAGS) -c $< #------------------------------------------------------------------------ $(TARGET): $(TARGET).exe lib$(TARGET).a #------------------------------------------------------------------------ $(TARGET).exe: $(TARGET_DEPENDS) rm -f $@ $(CCC) $(CCFLAGS) $(OBJS) $(LIBS) $(LDFLAGS) -o $@ #------------------------------------------------------------------------ lib$(TARGET).a: $(TARGET_DEPENDS) $(TARGET).exe rm -f $@ $(DLLTOOL) -l $@ -D $(TARGET).exe $(OBJS) $(LIBS) #------------------------------------------------------------ # If you are porting and using g++, you should use this file as a start, # for a "release" version, optimized with run-time tracing removed. # If you get errors or warnings, make a copy of it and modify that. # For the first cut, use "Make2.Debug" as the start for more tracing, # or "Make2.Trace" for an extreme amount of tracing. # After it works, use the file "Make2.g++" as a start for # executable to use. # If the port is non-trivial, check with me first because someone else # may have already done it. # If it works without changes, send me a note so I can put it in the docs. # Please send the changes to aldavis@gnu.org #------------------------------------------------------------ #------------------------------------------------------------ modelgen/Make3000066400000000000000000000060041145401216200135270ustar00rootroot00000000000000#$Id: Make3,v 26.133 2009/11/26 04:58:04 al Exp $ -*- Makefile -*- # Copyright (C) 2001 Albert Davis # Author: Albert Davis # # This file is part of "Gnucap", the Gnu Circuit Analysis Package # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. #------------------------------------------------------------------------ # Part 3 of a Makefile #------------------------------------------------------------------------ tags: $(HDRS) $(SRCS) etags --c++ $(HDRS) $(SRCS) #------------------------------------------------------------------------ checkin: date "+#define PATCHLEVEL \"%Y.%m.%d RCS `cat rcsversion`\"" \ >patchlev.h -ci -u`cat rcsversion` -m. -t/dev/null $(RAW) -ci -r`cat rcsversion` -m. -t/dev/null $(DELETED) $(GENERATED) touch patchlev.h #------------------------------------------------------------------------ checkout: co $(RAW) #------------------------------------------------------------------------ #unclean: # rm $(ALL) #------------------------------------------------------------------------ backup: -mkdir BACKUP cp $(RAW) BACKUP #------------------------------------------------------------------------ depend: Make.depend Make.depend: $(SRCS) $(HDRS) $(CCC) -MM $(CCFLAGS) $(SRCS) > Make.depend #----------------------------------------------------------------------------- date: date "+#define PATCHLEVEL \"%Y.%m.%d RCS `cat rcsversion` +\"" \ >patchlev.h #----------------------------------------------------------------------------- header-check: $(CCC) -o /dev/null $(RAW_HDRS) #----------------------------------------------------------------------------- manifest: MANIFEST MANIFEST: $(DISTFILES) echo $(DISTFILES) | sed 's/ /\n/g' >MANIFEST #----------------------------------------------------------------------------- md5sums: MD5SUMS MD5SUMS: $(DISTFILES) md5sum $(DISTFILES) | grep -v MD5SUMS >MD5SUMS #----------------------------------------------------------------------------- mostlyclean: rm -rf $(MOSTLYCLEANFILES) rm -f */*.o */*.obj */*.h */*.cc clean: rm -rf $(CLEANFILES) rm -f */*.o */*.obj */*.h */*.cc distclean: rm -rf $(DISTCLEANFILES) rm -f */*.o */*.obj */*.h */*.cc rm -f *~ \#*\# maintainer-clean: rm -rf $(MAINTAINERCLEANFILES) rm -f */*.o */*.obj */*.h */*.cc rm -f *~ \#*\# #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- modelgen/Makefile.am000066400000000000000000000027761145401216200147140ustar00rootroot00000000000000# -*- Automake -*- # # $Id: Makefile.am,v 26.70 2008/02/05 02:03:56 al Exp $ # # Process this file with autoconf to produce a configure script. # # # COPYRIGHT # # This file is part of "Gnucap", the Gnu Circuit Analysis Package # # Copyright (C) 2005 Dan McMahill # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. bin_PROGRAMS= gnucap-modelgen gnucap_modelgen_SOURCES= \ ap_construct.cc ap_convert.cc ap_get.cc ap_match.cc ap_skip.cc \ l_trim.cc u_opt1.cc io_out.cc io.cc \ ap.h io_.h io_error.h io_trace.h l_lib.h md.h patchlev.h u_opt.h mode.h \ mg_main.cc mg_error.cc mg_in.cc mg_out_h.cc mg_out_dump.cc \ mg_out_common.cc mg_out_dev.cc mg_out_lib.cc mg_out_model.cc mg_out_root.cc \ mg_.h mg_out.h declare.h EXTRA_DIST= \ Make1 Make3 Make.depend Make2.g++ Make2.Debug Make2.mingw32 \ configure.old Makefile.template INCLUDES= -I$(top_srcdir)/src modelgen/Makefile.in000066400000000000000000000421461145401216200147200ustar00rootroot00000000000000# Makefile.in generated by automake 1.11 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- Automake -*- # # $Id: Makefile.am,v 26.70 2008/02/05 02:03:56 al Exp $ # # Process this file with autoconf to produce a configure script. # # # COPYRIGHT # # This file is part of "Gnucap", the Gnu Circuit Analysis Package # # Copyright (C) 2005 Dan McMahill # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = gnucap-modelgen$(EXEEXT) subdir = modelgen DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_gnucap_modelgen_OBJECTS = ap_construct.$(OBJEXT) \ ap_convert.$(OBJEXT) ap_get.$(OBJEXT) ap_match.$(OBJEXT) \ ap_skip.$(OBJEXT) l_trim.$(OBJEXT) u_opt1.$(OBJEXT) \ io_out.$(OBJEXT) io.$(OBJEXT) mg_main.$(OBJEXT) \ mg_error.$(OBJEXT) mg_in.$(OBJEXT) mg_out_h.$(OBJEXT) \ mg_out_dump.$(OBJEXT) mg_out_common.$(OBJEXT) \ mg_out_dev.$(OBJEXT) mg_out_lib.$(OBJEXT) \ mg_out_model.$(OBJEXT) mg_out_root.$(OBJEXT) gnucap_modelgen_OBJECTS = $(am_gnucap_modelgen_OBJECTS) gnucap_modelgen_LDADD = $(LDADD) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(gnucap_modelgen_SOURCES) DIST_SOURCES = $(gnucap_modelgen_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EXEEXT = @EXEEXT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MODELGEN = @MODELGEN@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ gnucap_modelgen_SOURCES = \ ap_construct.cc ap_convert.cc ap_get.cc ap_match.cc ap_skip.cc \ l_trim.cc u_opt1.cc io_out.cc io.cc \ ap.h io_.h io_error.h io_trace.h l_lib.h md.h patchlev.h u_opt.h mode.h \ mg_main.cc mg_error.cc mg_in.cc mg_out_h.cc mg_out_dump.cc \ mg_out_common.cc mg_out_dev.cc mg_out_lib.cc mg_out_model.cc mg_out_root.cc \ mg_.h mg_out.h declare.h EXTRA_DIST = \ Make1 Make3 Make.depend Make2.g++ Make2.Debug Make2.mingw32 \ configure.old Makefile.template INCLUDES = -I$(top_srcdir)/src all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modelgen/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu modelgen/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) gnucap-modelgen$(EXEEXT): $(gnucap_modelgen_OBJECTS) $(gnucap_modelgen_DEPENDENCIES) @rm -f gnucap-modelgen$(EXEEXT) $(CXXLINK) $(gnucap_modelgen_OBJECTS) $(gnucap_modelgen_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ap_construct.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ap_convert.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ap_get.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ap_match.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ap_skip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io_out.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/l_trim.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mg_error.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mg_in.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mg_main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mg_out_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mg_out_dev.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mg_out_dump.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mg_out_h.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mg_out_lib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mg_out_model.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mg_out_root.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_opt1.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-binPROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: modelgen/Makefile.template000066400000000000000000000114601145401216200161200ustar00rootroot00000000000000#$Id: Makefile.template,v 26.34 2007/07/03 22:49:52 al Exp $ -*- Makefile -*- # Copyright (C) 2001 Albert Davis # Author: Albert Davis # # This file is part of "Gnucap", the Gnu Circuit Analysis Package # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. #------------------------------------------------------------------------ # In most cases you can just type "make" to build it. # Generally, you will want "make your-system". # Look in this file for the choices. # If yours is not here, look for a similar one and copy. # The special configurations listed here allow you to do multiple builds # from the same source directory, and patch some problems. #----------------------------------------------------------------------------- # The default is to use the makefile built by "configure" default: nothing -mkdir O cat Make1 Make2 Make3 Make.depend >O/Makefile (cd O; ${MAKE} -k) #----------------------------------------------------------------------------- # The most common configuration is g++ # This should work if it is properly installed # and has the proper libraries and headers. # It is optimized for speed. Debugging is off. g++: nothing -mkdir O cat Make1 Make2.g++ Make3 Make.depend >O/Makefile (cd O; ${MAKE} -k) #----------------------------------------------------------------------------- # This one makes a "debug" build ... # Asserts and some tracing is turned on. # It prints a trace when "untested" code is exercised. # "Untested" means the regressions don't test it. # It doesn't mean TOTALLY untested. debug: nothing -mkdir O-DEBUG cat Make1 Make2.Debug Make3 Make.depend >O-DEBUG/Makefile (cd O-DEBUG; ${MAKE} -k) #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # MS Windows using mingw32 mingw: nothing -mkdir MSW cat Make1 Make2.mingw32 Make3 Make.depend >MSW/Makefile (cd MSW; ${MAKE} -k) #----------------------------------------------------------------------------- tags: nothing cat Make1 Make2.g++ Make3 >Make.aux (${MAKE} tags -f Make.aux) #----------------------------------------------------------------------------- depend: nothing cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux depend #----------------------------------------------------------------------------- checkin: nothing cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux checkin #----------------------------------------------------------------------------- checkout: nothing cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux checkout #----------------------------------------------------------------------------- # Note that the /usr/local directory is overwritten by configure. install: nothing if test -d /usr/local/bin; then \ cp O/gnucap /usr/local/bin/gnucap; \ else \ mkdir -p /usr/local/bin && \ cp O/gnucap /usr/local/bin/gnucap; \ fi #----------------------------------------------------------------------------- uninstall: clean -rm /usr/local/bin/gnucap #----------------------------------------------------------------------------- unconfig: rm -f Makefile #----------------------------------------------------------------------------- date: nothing cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux date #----------------------------------------------------------------------------- manifest: cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux manifest #----------------------------------------------------------------------------- md5sums: cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux md5sums #----------------------------------------------------------------------------- mostlyclean: cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux mostlyclean clean: cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux clean distclean: cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux distclean maintainer-clean: cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux maintainer-clean #----------------------------------------------------------------------------- nothing: #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- modelgen/ap.h000066400000000000000000000173101145401216200134170ustar00rootroot00000000000000/*$Id: ap.h,v 26.130 2009/11/15 21:51:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * stuff for the "ap" family of parsing functions */ //testing=script,sparse 2006.07.17 #ifndef AP_H #define AP_H #include "md.h" /*--------------------------------------------------------------------------*/ char* getcmd(const char*,char*,int); /*--------------------------------------------------------------------------*/ enum AP_MOD{ mNONE, /* nothing special */ mSCALE, /* scale it after reading */ mOFFSET, /* add an offset */ mINVERT, /* save 1 / the number */ mPOSITIVE, /* store absolute value */ mOCTAL, /* read the number in octal */ mHEX /* read the number in hex */ }; const bool ONE_OF = false; class INTERFACE CS { public: enum STDIN {_STDIN}; enum INC_FILE {_INC_FILE}; enum WHOLE_FILE {_WHOLE_FILE}; enum STRING {_STRING}; private: FILE* _file; std::string _name; std::string _cmd; unsigned _cnt; unsigned _length; unsigned _begin_match; unsigned _end_match; bool _ok; int _line_number; public: // construction, destruction, and re-construction explicit CS(STDIN); explicit CS(INC_FILE, const std::string& name); explicit CS(WHOLE_FILE, const std::string& name); explicit CS(STRING, const std::string& s); explicit CS(const CS& p); CS& operator=(const std::string& s); CS& operator=(const CS& p); CS& get_line(const std::string& prompt); ~CS() {if (is_file()) {fclose(_file);}} // status - non-consuming unsigned cursor()const {return _cnt;} bool stuck(unsigned* last) {bool ok=*last<_cnt; *last=_cnt; return !ok;} bool gotit(unsigned last) {return last<_cnt;} operator bool()const {return _ok;} // get -- non-consuming const std::string fullstring()const {return _cmd;} const std::string substr(unsigned i)const {return ((_cmd.length()>=i) ? _cmd.substr(i) : "");} const std::string substr(unsigned i, unsigned n)const {return _cmd.substr(i,n);} const std::string tail()const {return substr(_cnt);} char peek()const {return _cmd[_cnt];} // status - may consume whitespace only bool ns_more()const {return peek()!='\0';} bool more() {skipbl(); return ns_more();} bool is_end() {return !more();} bool is_file() {return (_file && !isatty(fileno(_file)));} bool is_first_read()const {untested(); return (_line_number == 0);} // control CS& reset(unsigned c=0) {_cnt=c; _ok=true; return *this;} // exception handling (ap_error.cc) non-consuming CS& check(int, const std::string&); CS& warn(int, unsigned, const std::string&); CS& warn(int i, const std::string& s) {return warn(i,cursor(), s);} // string matching (ap_match.cc) possibly consuming, sets _ok CS& umatch(const std::string&); CS& scan(const std::string&); std::string last_match()const; std::string trimmed_last_match(const std::string& = " ,=;")const; // character tests - non-consuming, no _ok bool match1(char c)const{return (peek()==c);} bool match1(const std::string& c)const {return ns_more() && strchr(c.c_str(),peek());} size_t find1(const std::string& c)const {return ((ns_more()) ? c.find_first_of(peek()) : std::string::npos);} bool is_xdigit()const {untested(); return (match1("0123456789abcdefABCDEF"));} bool is_digit()const {return (match1("0123456789"));} bool is_pfloat()const {return (match1(".0123456789"));} bool is_float()const {return (match1("+-.0123456789"));} bool is_argsym()const {return (match1("*?$%_&@"));} bool is_alpha()const {return !!isalpha(toascii(peek()));} bool is_alnum()const {return !!isalnum(toascii(peek()));} bool is_term(const std::string& t = ",=(){};") {char c=peek(); return (c=='\0' || isspace(c) || match1(t));} // conversions (ap_convert.cc) always consuming char ctoc(); void ctostr(char*,int,const std::string&); std::string ctos(const std::string& term=",=(){};", const std::string& b="\"'{", const std::string& e="\"'}", const std::string& trap=""); std::string get_to(const std::string& term); // conversions (ap_convert.cc) consumes if successful, sets _ok double ctof(); bool ctob(); int ctoi(); unsigned ctou(); int ctoo(); int ctox(); double ctopf() {return std::abs(ctof());} CS& operator>>(bool& x) {x=ctob();return *this;} CS& operator>>(char& x) {untested(); x=ctoc();return *this;} CS& operator>>(int& x) {x=ctoi();return *this;} CS& operator>>(unsigned& x) {x=ctou();return *this;} CS& operator>>(double& x) {x=ctof();return *this;} CS& operator>>(std::string& x) {x=ctos();return *this;} // skip (ap_skip.cc) possibly consuming, sets _ok CS& skip(int c=1) {_cnt=static_cast(static_cast(_cnt)+c); _ok=_cnt<=_length; return *this;} CS& skipbl(); CS& skip1b(char); CS& skip1(char); CS& skip1b(const std::string&); CS& skip1(const std::string&); CS& skiparg(); CS& skipto1(const std::string&); CS& skipto1(char); CS& skipcom() {return skip1b(",");} CS& operator>>(const char& x) {return skip1b(x);} CS& operator>>(const char* x) {return umatch(x);} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ // these are non-member to provide a consistent interface, // like the templates to follow INTERFACE bool Get(CS& cmd, const std::string&, bool*); INTERFACE bool Get(CS& cmd, const std::string&, int*, AP_MOD=mNONE, int=0); INTERFACE bool Get(CS& cmd, const std::string&, double*, AP_MOD, double=0.); /*--------------------------------------------------------------------------*/ template bool Get(CS& cmd, const std::string& key, T* val) { if (cmd.umatch(key + " {=}")) { cmd >> *val; return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ template inline bool scan_get(CS& cmd, const std::string& key, T* val) { if (cmd.scan(key)) { cmd >> '=' >> *val; return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ template inline bool Set(CS& cmd, const std::string& key, T* val, T newval) { if (cmd.umatch(key + ' ')) { *val = newval; return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ template inline CS& operator>>(CS& cmd, T& val) { val.parse(cmd); return cmd; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif modelgen/ap_construct.cc000066400000000000000000000157351145401216200156720ustar00rootroot00000000000000/*$Id: ap_construct.cc,v 26.130 2009/11/15 21:51:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * construction, copy, etc. */ //testing=script,sparse 2006.07.17 #include "u_opt.h" #include "ap.h" #if defined(HAVE_LIBREADLINE) #include #include #endif /*--------------------------------------------------------------------------*/ static std::string getlines(FILE*); OMSTREAM mout; // > file bitmap //BUG//encapsulation OMSTREAM mlog; // log file bitmap /*--------------------------------------------------------------------------*/ CS::CS(CS::STDIN) :_file(stdin), _name(), _cmd(), _cnt(0), _length(0), _begin_match(0), _end_match(0), _ok(true), _line_number(0) { } /*--------------------------------------------------------------------------*/ CS::CS(CS::INC_FILE, const std::string& name) :_file(fopen(name.c_str(), "r")), _name(name), _cmd(), _cnt(0), _length(0), _begin_match(0), _end_match(0), _ok(true), _line_number(0) { if (!_file) {itested(); throw Exception_File_Open(name + ':' + strerror(errno)); }else{ } } /*--------------------------------------------------------------------------*/ CS::CS(CS::WHOLE_FILE, const std::string& name) :_file(NULL), _name(name), _cmd(), _cnt(0), _length(0), _begin_match(0), _end_match(0), _ok(true), _line_number(0) { int f = open(name.c_str(), O_RDONLY); if (f == EOF) {itested(); throw Exception_File_Open(name + ':' + strerror(errno)); }else{ } _length = static_cast(lseek(f, off_t(0), SEEK_END)); lseek(f, off_t(0), SEEK_SET); char* cmd = new char[_length+2]; read(f, cmd, _length); cmd[_length++] = '\0'; _cmd = cmd; close(f); } /*--------------------------------------------------------------------------*/ CS::CS(CS::STRING, const std::string& s) :_file(NULL), _name(), _cmd(s), _cnt(0), _length(static_cast(s.length())), _begin_match(0), _end_match(0), _ok(true), _line_number(0) { } /*--------------------------------------------------------------------------*/ #if 0 CS::CS(const CS& p) :_file(NULL), _name(p._name), _cmd(p._cmd), _cnt(p._cnt), _length(p._length), _begin_match(0), _end_match(0), _ms(p._ms), _ok(p._ok), _line_number(0) {untested(); } #endif /*--------------------------------------------------------------------------*/ CS& CS::operator=(const std::string& s) {untested(); assert(!_file); _cmd = s; _cnt = 0; _ok = true; _length = static_cast(s.length()); return *this; } /*--------------------------------------------------------------------------*/ #if 0 CS& CS::operator=(const CS& p) {untested(); assert(&p != this); _name = p._name; _file = p._file; _cmd = p._cmd; _cnt = p._cnt; _ok = p._ok; _length = p._length; return *this; } #endif /*--------------------------------------------------------------------------*/ CS& CS::get_line(const std::string& prompt) { ++_line_number; if (is_file()) { _cmd = getlines(_file); _cnt = 0; _length = static_cast(_cmd.length()); _ok = true; }else{itested(); assert(_file == stdin); char cmdbuf[BUFLEN]; getcmd(prompt.c_str(), cmdbuf, BUFLEN); _cmd = cmdbuf; _cnt = 0; _length = static_cast(_cmd.length()); _ok = true; } if (OPT::listing) { IO::mstdout << "\"" << fullstring() << "\"\n"; }else{ } return *this; } /*--------------------------------------------------------------------------*/ /* getcmd: get a command. * if "fin" is stdin, display a prompt first. * Also, actually do logging, echo, etc. */ char *getcmd(const char *prompt, char *buffer, int buflen) { assert(prompt); assert(buffer); if (isatty(fileno(stdin))) { // stdin is keyboard #if defined(HAVE_LIBREADLINE) if (OPT::edit) { char* line_read = readline(prompt); if (!line_read) {itested(); throw Exception_End_Of_Input("EOF on stdin"); }else{ } // readline gets a new buffer every time, so copy it to where we want it char* end_of_line = (char*)memccpy(buffer, line_read, 0, static_cast(buflen-1)); if (!end_of_line) { buffer[buflen-1] = '\0'; }else{ *end_of_line = '\0'; } free(line_read); if (*buffer) { add_history(buffer); }else{ } }else #endif { IO::mstdout << prompt; /* prompt & flush buffer */ if (!fgets(buffer, buflen, stdin)) {untested(); /* read line */ throw Exception_End_Of_Input("EOF on stdin"); }else{ } } (IO::mstdout - mout) << '\r'; /* reset col counter */ trim(buffer); (mlog + mout) << buffer << '\n'; return buffer; }else{ // stdin is file if (!fgets(buffer, buflen, stdin)) {itested(); /* read line */ throw Exception_End_Of_Input("EOF on stdin"); }else{ } trim(buffer); (mlog + mout) << buffer << '\n'; return buffer; } } /*--------------------------------------------------------------------------*/ static std::string getlines(FILE *fileptr) { assert(fileptr); const int buffer_size = BIGBUFLEN; std::string s; bool need_to_get_more = true; // get another line (extend) while (need_to_get_more) { char buffer[buffer_size+1]; char* got_something = fgets(buffer, buffer_size, fileptr); if (!got_something) { // probably end of file need_to_get_more = false; if (s == "") { throw Exception_End_Of_Input(""); }else{untested(); } }else{ trim(buffer); size_t count = strlen(buffer); if (buffer[count-1] == '\\') {itested(); buffer[count-1] = '\0'; }else{ // look ahead at next line //int c = fgetc(fileptr); int c; while (isspace(c = fgetc(fileptr))) { // skip } if (c == '+') { need_to_get_more = true; }else if (c == '\n') {unreachable(); need_to_get_more = true; ungetc(c,fileptr); }else{ need_to_get_more = false; ungetc(c,fileptr); } } s += buffer; s += ' '; } } return s; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/ap_convert.cc000066400000000000000000000217731145401216200153250ustar00rootroot00000000000000/*$Id: ap_convert.cc,v 26.125 2009/10/15 20:58:21 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script 2006.07.17 #include "u_opt.h" #include "ap.h" /*--------------------------------------------------------------------------*/ // char CS::ctoc(); // void CS::ctostr(char* d, int l, const string& t); // string CS::ctos(const string& term); // int CS::ctoi(); // unsigned CS::ctou(); // int CS::ctoo(); // int CS::ctox(); // double CS::ctof(); /*--------------------------------------------------------------------------*/ /* ctoc: character input to character */ char CS::ctoc() { char c=_cmd[_cnt]; if(_cnt<=_length) { ++_cnt; }else{untested(); } return c; } /*--------------------------------------------------------------------------*/ /* ctostr: character input to string * scan (and eat) an input string (cmd) using index (cnt). * result in (des) (null terminated). * max length (actual char count) is (len). * (des) must be at least (len)+1 characters long. * (cmd) unchanged. (*cnt) updated to point to next argument. * skips leading whitespace. skips trailing whitespace and comma * skips parts of input word too big for destination */ void CS::ctostr(char* des, int len, const std::string& term) { skipbl(); int ii; for (ii = 0; ii < len && !is_term(term); ++ii) { des[ii] = ctoc(); } des[ii] = '\0'; while (!is_term(term)) {untested(); skip(); } skipcom(); } /*--------------------------------------------------------------------------*/ std::string CS::ctos(const std::string& term, const std::string& begin_quote, const std::string& end_quote, const std::string& trap) { assert(begin_quote.length() == end_quote.length()); skipbl(); unsigned begin_string = cursor(); unsigned end_string = cursor(); std::string s; std::string::size_type which_quote = find1(begin_quote); if (which_quote != std::string::npos) { int quotes = 1; skip(); // the quote begin_string = cursor(); char the_begin_quote = begin_quote[which_quote]; char the_end_quote = end_quote[which_quote]; for (;;) { if (!ns_more()) {itested(); end_string = cursor(); warn(bDANGER, std::string("need ") + the_end_quote); break; }else if (skip1(the_end_quote)) { if (--quotes <= 0) { end_string = cursor() - 1; break; }else{ } }else if (skip1(the_begin_quote)) { ++quotes; skip(); }else if (skip1('\\')) { end_string = cursor() - 1; s += _cmd.substr(begin_string, end_string-begin_string); begin_string = cursor(); skip1(the_end_quote); }else{ skip(); } } s += _cmd.substr(begin_string, end_string-begin_string); }else{ while(ns_more() && !is_term(term)) { skip(); } if (match1(trap)) {untested(); warn(bDANGER, "ap_convert trap-exit"); }else{ } end_string = cursor(); s = _cmd.substr(begin_string, end_string-begin_string); } skipcom(); _ok = end_string > begin_string; return s; } /*--------------------------------------------------------------------------*/ std::string CS::get_to(const std::string& term) { std::string des; while(ns_more() && !match1(term)) { des += ctoc(); } return des; } /*--------------------------------------------------------------------------*/ /* ctob: character input to bool * no match makes it true; * Mismatch belongs to next token */ bool CS::ctob() { skipbl(); unsigned here = cursor(); bool val = true; ONE_OF || Set(*this, "1", &val, true) || Set(*this, "0", &val, false) || Set(*this, "t{rue}", &val, true) || Set(*this, "f{alse}", &val, false) || Set(*this, "y{es}", &val, true) || Set(*this, "n{o}", &val, false) || Set(*this, "#t{rue}", &val, true) || Set(*this, "#f{alse}",&val, false) ; skipcom(); _ok = cursor() > here; return val; } /*--------------------------------------------------------------------------*/ /* ctoi: character input to integer * Returns signed integer, or 0 if the string is not a number. * Input must be integer: no multipliers, no decimal point. * Dot or letter belongs to the next token. */ int CS::ctoi() { int val = 0; int sign = 1; skipbl(); unsigned here = cursor(); if (skip1("-")) { sign = -1; }else{ skip1("+"); } while (is_digit()) { val = 10 * val + (ctoc()-'0'); } skipcom(); _ok = cursor() > here; return val * sign; } /*--------------------------------------------------------------------------*/ /* ctou: character input to unsigned integer * Returns unsigned integer, or 0 if the string is not a number. * Input must be integer: no multipliers, no decimal point. * Dot or letter belongs to the next token. */ unsigned CS::ctou() { unsigned val = 0; skipbl(); unsigned here = cursor(); while (is_digit()) { val = 10 * val + static_cast(ctoc()-'0'); } skipcom(); _ok = cursor() > here; return val; } /*--------------------------------------------------------------------------*/ /* ctoo: character octal input to integer * Returns integer, or 0 if the string is not a number. * Input must be integer: no multipliers, no decimal point. * Dot or letter belongs to the next token. * There is no check against '8' and '9'. */ int CS::ctoo() { int val = 0; skipbl(); unsigned here = cursor(); while (is_digit()) { val = 8 * val + (ctoc()-'0'); } skipcom(); _ok = cursor() > here; return val; } /*--------------------------------------------------------------------------*/ /* ctox: character hex input to unsigned integer * Returns integer, or 0 if the string is not a number. * Input must be hex integer: no multipliers, no decimal point. * Dot or letter belongs to the next token. */ int CS::ctox() {untested(); int val = 0; skipbl(); unsigned here = cursor(); while (is_xdigit()) {untested(); if (is_digit()) {untested(); val = 16 * val + (ctoc()-'0'); }else{untested(); val = 16 * val + (tolower(ctoc())-'a'+10); } } skipcom(); _ok = cursor() > here; return val; } /*--------------------------------------------------------------------------*/ /* ctof: floating point input * return double number if got, else 0 * supports letter multipliers (spice style) * skips trailing letters (10uhenries == 10u) * skips trailing spaces and one comma * pointer points to char following comma * or first non-space following number just got * or first non-space (if non-number) */ double CS::ctof() { double val = 0.0; double power = 1.0; int sign = 1; skipbl(); if (!is_float()) { skipcom(); _ok = false; return 0.; }else{ } if (skip1("-")) { // sign sign = -1; }else{ skip1("+"); } while (is_digit()) { // up to dec pt val = 10.0 * val + (ctoc()-'0'); } skip1("."); // dec pt while (is_digit()) { // after dec pt val = 10.0 * val + (ctoc()-'0'); power *= .1; } if (skip1("eE")) { // exponent: E form int expo = 0; int es = 1; if (skip1("-")) { es = -1; }else{ skip1("+"); } while (is_digit()) expo = 10 * expo + (ctoc()-'0'); expo *= es; power *= pow(10., expo); }else if ((OPT::units == uSPICE) && skip1("mM")) { // M is special if (skip1("eE")) { // meg power *= 1e6; }else if (skip1("iI")) { // mil power *= 25.4e-6; }else{ // plain m (milli) power *= 1e-3; } }else if (skip1("M")) { assert(OPT::units == uSI); power *= 1e6; }else if (skip1("m")) { assert(OPT::units == uSI); power *= 1e-3; }else if (skip1("uU")) { // other letters power *= 1e-6; }else if (skip1("nN")) { power *= 1e-9; }else if (skip1("p")) { power *= 1e-12; }else if (skip1("P")) { power *= ((OPT::units == uSI) ? (1e15) : 1e-12); }else if (skip1("fF")) { power *= 1e-15; }else if (skip1("kK")) { power *= 1e3; }else if (skip1("gG")) { power *= 1e9; }else if (skip1("tT")) { power *= 1e12; }else if (skip1("%")) {untested(); power *= 1e-2; }else{ } while (is_alpha()) { // skip letters skip(); } skipcom(); _ok = true; return (sign*val*power); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/ap_get.cc000066400000000000000000000060271145401216200144170ustar00rootroot00000000000000/*$Id: ap_get.cc,v 26.85 2008/06/19 05:01:15 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * get value for matching keyword */ //testing=script 2006.07.17 #include "ap.h" /*--------------------------------------------------------------------------*/ /* special version of "get" for "bool" * so "nofoo" works as an equivalent to foo=false */ bool Get(CS& cmd, const std::string& key, bool* val) { if (cmd.umatch(key + ' ')) { if (cmd.skip1b('=')) {itested(); cmd >> *val; }else{ *val = true; } return true; }else if (cmd.umatch("no" + key)) { *val = false; return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ bool Get(CS& cmd, const std::string& key, int* val, AP_MOD mod, int scale) { if (cmd.umatch(key + " {=}")) { switch(mod) { case mNONE: *val = int(cmd.ctof()); break; case mSCALE: untested(); *val = int(cmd.ctof())*scale; break; case mOFFSET: untested(); *val = int(cmd.ctof())+scale; break; case mINVERT: untested(); *val = 1 / int(cmd.ctof()); break; case mPOSITIVE: untested(); *val = std::abs(int(cmd.ctof())); break; case mOCTAL: *val = cmd.ctoo(); break; case mHEX: untested(); *val = cmd.ctox(); break; } return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ bool Get(CS& cmd, const std::string& key, double* val, AP_MOD mod, double scale) { if (cmd.umatch(key + " {=}")) { switch(mod) { case mNONE: untested(); *val = cmd.ctof(); break; case mSCALE: untested(); *val = cmd.ctof()*scale; break; case mOFFSET: untested(); *val = cmd.ctof()+scale; break; case mINVERT: untested(); *val = 1 / cmd.ctof(); break; case mPOSITIVE: *val = std::abs(cmd.ctof()); break; case mOCTAL: untested(); *val = cmd.ctoo(); break; case mHEX: untested(); *val = cmd.ctox(); break; } return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/ap_match.cc000066400000000000000000000066351145401216200147410ustar00rootroot00000000000000/*$Id: ap_match.cc,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * string compare */ //testing=script 2006.07.17 #include "u_opt.h" #include "ap.h" /*--------------------------------------------------------------------------*/ /* umatch = universal match */ CS& CS::umatch(const std::string& s) { unsigned start = cursor(); skipbl(); unsigned begin_match = cursor(); const char* str2 = s.c_str(); bool optional = 0; for (;;) { if ((!*str2) || (*str2 == '|')) { _ok = true; break; }else if ((str2[0] == '\\') && (peek() == str2[1])) { skip(); str2 += 2; }else if ((!optional) && (*str2 == '{')) { ++str2; optional = true; }else if ((optional) && (*str2 == '}')) { ++str2; optional = false; }else if ((*str2 == ' ') && is_term()) { // blank in ref string matches anything that delimits tokens skipbl(); ++str2; }else if (peek() == *str2) { skip(); ++str2; }else if ((OPT::case_insensitive) && (tolower(peek()) == tolower(*str2))) { skip(); ++str2; }else if (optional) { while (*str2 != '}') { ++str2; } }else{ // mismatch const char* bar = strchr(str2, '|'); if (bar && (bar[-1] != '\\')) { str2 = bar+1; reset(start); }else{ _ok = false; break; } } } if (_ok) { _begin_match = begin_match; _end_match = cursor(); skipcom(); _ok = true; }else{ reset(start); _ok = false; } return *this; } /*--------------------------------------------------------------------------*/ CS& CS::scan(const std::string& s) { unsigned start = cursor(); for (;;) { if (umatch(s)) { // found it _ok = true; break; }else if (!more()) { // ran out reset(start); _ok = false; break; }else{ // skip and try again skiparg(); } } return *this; } /*--------------------------------------------------------------------------*/ std::string CS::last_match()const { return _cmd.substr(_begin_match, _end_match-_begin_match); } /*--------------------------------------------------------------------------*/ std::string CS::trimmed_last_match(const std::string& suf)const { unsigned real_end = _end_match; while (strchr(suf.c_str(), _cmd[real_end-1])) { --real_end; } return _cmd.substr(_begin_match, real_end-_begin_match); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/ap_skip.cc000066400000000000000000000075561145401216200146160ustar00rootroot00000000000000/*$Id: ap_skip.cc,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * collection of functions to skip input * all except skip1 skip leading whitespace, skip whatever is being skipped, * then skip trailing whitespace. */ //testing=script 2006.07.17 #include "ap.h" /*--------------------------------------------------------------------------*/ /* skipbl: skip whitespace. (any non-graphic character is ws) * =,(,) are also ws * update string pointer * pointer points to first non-space * does NOT update _ok flag */ CS& CS::skipbl() { while (peek() && (!isgraph(peek()))) { skip(); } return *this; } /*--------------------------------------------------------------------------*/ /* skip1b: skip 1 matching character and surrounding blanks * _ok = did it */ CS& CS::skip1b(char t) { skipbl(); skip1(t); skipbl(); return *this; } /*--------------------------------------------------------------------------*/ /* skip1: skip 1 character matching any in t * _ok = did it */ CS& CS::skip1(char t) { if (match1(t)) { skip(); assert(_ok); }else{ _ok = false; } return *this; } /*--------------------------------------------------------------------------*/ /* skip1b: skip 1 matching character and surrounding blanks * _ok = did it */ CS& CS::skip1b(const std::string& t) { skipbl(); skip1(t); skipbl(); return *this; } /*--------------------------------------------------------------------------*/ /* skip1: skip 1 character matching any in t * _ok = did it */ CS& CS::skip1(const std::string& t) { if (match1(t)) { skip(); assert(_ok); }else{ _ok = false; } return *this; } /*--------------------------------------------------------------------------*/ /* skiparg: skip an argument (maybe just a comma) * _ok = skipped something */ CS& CS::skiparg() { unsigned here = cursor(); if (!skipcom()) { if (peek()) { skip(); }else{ } while (is_alpha() || is_float() || is_argsym()) { skip(); } skipcom(); }else{untested(); // empty field, just a comma } _ok = cursor() > here; return *this; } /*--------------------------------------------------------------------------*/ /* skipto: skip to a character (one of ...) * _ok = skipped something */ CS& CS::skipto1(const std::string& t) {untested(); unsigned here = cursor(); while (ns_more() && !match1(t)) {untested(); skip(); } _ok = ns_more(); if (!_ok) {untested(); reset(here); }else{untested(); } return *this; } /*--------------------------------------------------------------------------*/ /* skipto: skip to a character (explicit) * _ok = skipped something */ CS& CS::skipto1(char c) { unsigned here = cursor(); while (ns_more() && !match1(c)) { skip(); } _ok = ns_more(); if (!_ok) {untested(); reset(here); }else{ } return *this; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/configure.old000077500000000000000000000026111145401216200153300ustar00rootroot00000000000000#!/bin/sh mkdir O echo "CCFLAGS = \\" >Make.ccflags echo "LIBS = \\" >Make.libs echo "-DUNIX -O2 -DNDEBUG -I.. -I. -W" >>Make.ccflags echo "" >>Make.libs echo "" >>Make.libs cat <Make.sys #------------------------------------------------------------------------ VPATH = .:.. CCC = g++ LDFLAGS = .SUFFIXES : .o .cc .cc.o:; \$(CCC) \$(CCFLAGS) -c \$< #------------------------------------------------------------------------ \$(TARGET): \$(OBJS) rm -f \$@ \$(CCC) \$(CCFLAGS) \$(OBJS) -o \$@ \$(LIBS) \$(LDFLAGS) #------------------------------------------------------------------------ CAT_EOF cat Make.ccflags Make.libs Make.sys >Make2 cat Make1 Make2 Make3 Make.depend >O/Makefile #------------- Stuff added to enable --prefix -------------- if test "x$1" != "x"; then # echo Found input parameter -- $1 # Now see if the parameter is --prefix= if test "x${1#--prefix=}" != "x$1"; then # echo "Found --prefix in input args. Setting prefix directory." prefix=${1#--prefix=} else # echo "Found unrecognized parameter in input args." # Just use the default prefix dir. prefix=/usr/local fi else # echo "No input parameter found." # Just use the default prefix dir prefix=/usr/local fi sed -e "s#/usr/local#$prefix#" Makefile.template > Makefile #---------------------------------------------------------------- exit 0 modelgen/declare.h000066400000000000000000000000631145401216200144130ustar00rootroot00000000000000/* dummy file, to cover some code in transition */ modelgen/io.cc000066400000000000000000000024361145401216200135670ustar00rootroot00000000000000/*$Id: io.cc,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * shared data for all io functions, initialization, default values */ //testing=trivial 2006.07.17 #include "io_.h" OMSTREAM IO::mstdout(stdout); OMSTREAM IO::error(stdout); OMSTREAM IO::plotout; bool IO::plotset(false); int IO::formaat(0); bool IO::incipher(false); FILE* IO::stream[MAXHANDLE+1] = {0, stdout, stderr}; modelgen/io_.h000066400000000000000000000112711145401216200135650ustar00rootroot00000000000000/*$Id: io_.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * shared data for all io functions * other io related stuff, like files and formatting */ //testing=script 2006.07.17 #ifndef IO_H #define IO_H #include "l_lib.h" /*--------------------------------------------------------------------------*/ class CS; const int MAXHANDLE = CHAR_BIT*sizeof(int)-1; /*--------------------------------------------------------------------------*/ class INTERFACE OMSTREAM { private: int _mask; int _fltdig; /* max precision for float/double numbers */ int _fltwid; /* fixed(min)width for float/double numbers */ int _format; /* how to format io. Basic option. */ static unsigned _cpos[MAXHANDLE+1];/* character counter */ bool _cipher; /* flag: encrypt output file */ bool _pack; /* flag: convert whitespace to tabs on out */ OMSTREAM(int m) :_mask(m),_fltdig(7),_fltwid(0),_format(0),_cipher(false),_pack(false) {} public: explicit OMSTREAM(FILE* f = 0) :_mask(0),_fltdig(7),_fltwid(0),_format(0),_cipher(false), _pack(false) {_mask = (f) ? 1<(p));} OMSTREAM& form(const char*,...); OMSTREAM& operator<<(char c); OMSTREAM& operator<<(const char* s); OMSTREAM& operator<<(double x) {return (*this)< * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=trivial 2006.07.17 #ifndef bDANGER //#include "md.h" included by //#include "io_trace.h" /*--------------------------------------------------------------------------*/ /* arg to error() (badness) to decide severity of exception */ #define bNOERROR 0 #define bTRACE 1 #define bLOG 2 #define bDEBUG 3 #define bPICKY 4 #define bWARNING 5 #define bDANGER 6 INTERFACE void error(int,const char*,...); INTERFACE void error(int,const std::string&); INTERFACE std::string to_string(int); /*--------------------------------------------------------------------------*/ struct Exception { std::string _message; virtual const std::string message()const {return _message;} Exception(const std::string& Message) :_message(Message) { } virtual ~Exception() {} }; class CS; struct Exception_CS :public Exception { std::string _cmd; unsigned _cursor; const std::string message()const; //Exception_CS(const std::string& Message, const CS& cmd, unsigned cursor); Exception_CS(const std::string& Message, const CS& cmd); }; struct Exception_No_Match :public Exception{ std::string _key; Exception_No_Match(const std::string& key) :Exception("no match: " + key), _key(key) { } }; struct Exception_Cant_Find :public Exception{ std::string _device, _key, _scope; Exception_Cant_Find(const std::string& dev, const std::string& key, const std::string& scope) :Exception(dev + ": can't find: " + key + " in " + scope), _device(dev), _key(key), _scope(scope) { } Exception_Cant_Find(const std::string& dev, const std::string& key) :Exception(dev + ": can't find: " + key), _device(dev), _key(key), _scope("") { } }; struct Exception_Too_Many :public Exception{ int _requested, _max, _offset; Exception_Too_Many(int requested, int max, int offset) :Exception("too many: requested=" + to_string(requested+offset) + " max=" + to_string(max+offset)), _requested(requested), _max(max), _offset(offset) {untested(); } }; struct Exception_Type_Mismatch :public Exception{ std::string _device, _name, _need_type; Exception_Type_Mismatch(const std::string& dev, const std::string& name, const std::string& type) :Exception(dev + ": " + name + " is not a " + type), _device(dev), _name(name), _need_type(type) { } }; struct Exception_Model_Type_Mismatch :public Exception{ std::string _device, _modelname, _need_type; Exception_Model_Type_Mismatch(const std::string& d, const std::string& m, const std::string& n) :Exception(d + ": model " + m + " is not a " + n), _device(d), _modelname(m), _need_type(n) { } }; struct Exception_End_Of_Input :public Exception{ Exception_End_Of_Input(const std::string& Message) :Exception(Message) { } }; struct Exception_File_Open :public Exception{ Exception_File_Open(const std::string& Message) :Exception(Message) { } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif modelgen/io_out.cc000066400000000000000000000146251145401216200144610ustar00rootroot00000000000000/*$Id: io_out.cc,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * output text to files, devices, or whatever * m???? = multiple output to a bunch of io devices. * with character count (so tab will work) * Will start a new line first if the entire output will not fit. * so wrap will not break a word or number. * Where is a bit mask of places to send the output. * A possible portability problem exists with the handle numbers. * It assumes they start at 0, and count up, and that there are no more than * the number of bits in an integer (MAXHANDLE). * but I have yet to find a system that did not meet this form. */ //testing=script,sparse 2006.07.17 #include "u_opt.h" /*--------------------------------------------------------------------------*/ const char* octal(int x); // OMSTREAM & OMSTREAM::tab(int count) // OMSTREAM & OMSTREAM::form(const char*,...); // OMSTREAM & OMSTREAM::operator<<(const char *str) // OMSTREAM & OMSTREAM::operator<<(char chr) /*--------------------------------------------------------------------------*/ unsigned OMSTREAM::_cpos[MAXHANDLE+1]; /* character counter */ /*--------------------------------------------------------------------------*/ /* octal: make octal string for an int */ const char* octal(int x) { static char s[sizeof(int)*3+1]; sprintf(s, "%o", x); return s; } /*--------------------------------------------------------------------------*/ /* mtab: tab to column "count" on output devices "where" * by outputting spaces. * If already beyond, start new line, then tab to column. */ OMSTREAM & OMSTREAM::tab(unsigned count) { for (int ii=0, mm=1; ii<=MAXHANDLE; ++ii, mm<<=1) { if (_mask & mm) { OMSTREAM this_file(_mask & mm); if (_cpos[ii] > count) { this_file << '\n'; }else{ } while (_cpos[ii]= OPT::outwidth && _cpos[ii] != 0) { OMSTREAM this_file(_mask & mm); this_file << '\n' << '+'; }else{ } /* see if it fits .... */ if (_cpos[ii]==0) { /* if not, next line */ newline = true; }else{ } } if (cipher() && newline) {untested(); *this << '\t'; }else{ } while (*str && (str[1] || *str != '@')) { *this << *str++; } return *this; } /*--------------------------------------------------------------------------*/ /* mputc: multiple putc * multiple putc * also.... * crunch spaces, if selected * encripts, if selected * keeps track of character count */ OMSTREAM & OMSTREAM::operator<<(char chr) { if (_mask & 1) { unreachable(); _mask &= ~1; error(bDANGER, "internal error: out to stdin\n"); }else{ } static int old = '\0'; static int cchr = 'w'; /* starting encryption seed */ /* arbitrary printable character */ bool count; if (chr=='\t') {itested(); chr = ' '; count = false; }else{ count = true; } bool suppress = (pack() && old==' ' && chr==' '); old = chr; if (cipher() && !suppress && isprint(chr)) {untested(); cchr += static_cast(chr); while (!isascii(cchr) || !isprint(cchr)) {untested(); cchr -= (0x7f-0x20); } chr = static_cast(cchr); }else{ } for (int ii=0, mm=1; ii<=MAXHANDLE; ++ii, mm<<=1) { if (_mask & mm) { assert(IO::stream[ii]); if (chr=='\b') {untested(); --_cpos[ii]; fflush(IO::stream[ii]); }else if (count) { ++_cpos[ii]; }else{itested(); } if (chr=='\n') { _cpos[ii] = 0; fflush(IO::stream[ii]); }else if (chr=='\r') {itested(); if (_cpos[ii] == 0) {untested(); suppress = true; }else{itested(); _cpos[ii] = 0; fflush(IO::stream[ii]); } }else{ } if (!suppress) { fputc(chr,IO::stream[ii]); }else{itested(); } }else{ } } return *this; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/io_trace.h000066400000000000000000000055561145401216200146150ustar00rootroot00000000000000/*$Id: io_trace.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * trace macros for model debugging */ //testing=trivial 2006.07.17 /* allow multiple inclusions with different DO_TRACE */ #undef trace_line #undef trace0 #undef trace1 #undef trace2 #undef trace3 #undef trace4 #undef trace5 #undef untested #undef unreachable #undef incomplete /*--------------------------------------------------------------------------*/ #ifdef DO_TRACE #define trace_line() (printf("@@#\n@#@:%s:%u:%s\n", \ __FILE__, __LINE__, __func__)) #define trace0(s) (printf("@#@%s\n", s)) #define trace1(s,x) (printf("@#@%s %s=%g\n", s, #x, (double)(x))) #define trace2(s,x,y) (printf("@#@%s %s=%g %s=%g\n",\ s, #x, (double)(x), #y, (double)(y))) #define trace3(s,x,y,z) (printf("@#@%s %s=%g %s=%g %s=%g\n",\ s, #x, (double)(x), #y, (double)(y), #z, (double)(z))) #define trace4(s,w,x,y,z)(printf("@#@%s %s=%g %s=%g %s=%g %s=%g\n",\ s, #w, (double)(w), #x, (double)(x), #y, (double)(y), #z, (double)(z))) #define trace5(s,v,w,x,y,z)\ (printf("@#@%s %s=%g %s=%g %s=%g %s=%g %s=%g\n",\ s, #v, (double)(v), #w, (double)(w), #x, (double)(x),\ #y, (double)(y), #z, (double)(z))) #else #define trace_line() #define trace0(s) #define trace1(s,x) #define trace2(s,x,y) #define trace3(s,x,y,z) #define trace4(s,w,x,y,z) #define trace5(s,v,w,x,y,z) #endif #define unreachable() (printf("@@#\n@@@unreachable:%s:%u:%s\n", \ __FILE__, __LINE__, __func__)) #define incomplete() (printf("@@#\n@@@incomplete:%s:%u:%s\n", \ __FILE__, __LINE__, __func__)) #ifdef TRACE_UNTESTED #define untested() (printf("@@#\n@@@:%s:%u:%s\n", \ __FILE__, __LINE__, __func__)) #else #define untested() #endif #ifdef TRACE_ITESTED #define itested() (printf("@@#\n@@@:%s:%u:%s\n", \ __FILE__, __LINE__, __func__)) #else #define itested() #endif /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/l_lib.h000066400000000000000000000053371145401216200141060ustar00rootroot00000000000000/*$Id: l_lib.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script 2006.07.13 #ifndef L_LIB_H #define L_LIB_H #include "md.h" /*--------------------------------------------------------------------------*/ char* trim(char*); INTERFACE bool Umatch(const std::string&, const std::string&); INTERFACE bool wmatch(const std::string& s1,const std::string& s2); INTERFACE std::string to_string(unsigned); INTERFACE std::string to_string(int); INTERFACE std::string to_string(double); INTERFACE char* ftos(double,int,int,int); /*--------------------------------------------------------------------------*/ //ftos stuff enum { /* formatting bit-fields */ ftos_DEFAULT = 0, /* default formatting, with letters */ ftos_EXP = 1, /* use 'e' notation, almost like printf */ ftos_SIGN = 2, /* always include sign */ ftos_FILL = 4 /* fill in trailing zeros */ }; /*--------------------------------------------------------------------------*/ // wrappers for old standard C lpbrary namespace OS { inline void system(const std::string& s) {itested(); ::system(s.c_str()); } inline void chdir(const std::string& s) {itested(); ::chdir(s.c_str()); } inline void remove(const std::string& s) {itested(); ::remove(s.c_str()); } inline bool access_ok(const std::string& file, int mode) { return (::access(file.c_str(), mode) == 0/*file_ok*/); } inline std::string getcwd() {itested(); char buf[BUFLEN+1]; char* cwd = ::getcwd(buf,BUFLEN); if (cwd) {itested(); return cwd; }else{untested(); return ""; } } inline std::string getenv(const std::string& s) { char* ev = ::getenv(s.c_str()); if (ev) { return ev; }else{itested(); return ""; } } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif modelgen/l_trim.cc000066400000000000000000000031051145401216200144400ustar00rootroot00000000000000/*$Id: l_trim.cc,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * remove whitespace from the end of strings */ //testing=script,complete 2006.07.13 #include #include /*--------------------------------------------------------------------------*/ char* trim(char*); /*--------------------------------------------------------------------------*/ char* trim(char *string) { size_t idx = strlen(string); while (idx > 0 && !isgraph(string[--idx])) { string[idx] = '\0' ; } return string; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/md.h000066400000000000000000000147601145401216200134250ustar00rootroot00000000000000/*$Id: md.h,v 26.112 2009/07/24 00:10:32 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Machine dependent, configuration, and standard includes */ //testing=trivial 2006.07.17 #ifndef MD_H_INCLUDED #define MD_H_INCLUDED /*--------------------------------------------------------------------------*/ /* autoconf stuff */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /*--------------------------------------------------------------------------*/ /* std collection of includes */ // system #include #include #include #include #include #include #include #include #include #include #include #include #include // types #include #include // containers #include #include #include #include #include // algorithms #include #include /* usual but non-standard (POSIX??) collection of includes */ #include /* chdir, access, getcwd */ #include /* old style unix files */ /*--------------------------------------------------------------------------*/ /* constants related to memory size, word size, etc */ enum { BUFLEN = 256, BIGBUFLEN = 4096 }; /*--------------------------------------------------------------------------*/ /* user interface preferences */ #define I_PROMPT "gnucap> " #define CKT_PROMPT ">" #define ANTI_COMMENT "*>" #define DEFAULT_LANGUAGE "acs" /*--------------------------------------------------------------------------*/ #if defined(__WIN32__) #define ENDDIR "/\\" #define PATHSEP ';' #define SYSTEMSTARTFILE "gnucap.rc" #define SYSTEMSTARTPATH OS::getenv("PATH") #define USERSTARTFILE "gnucap.rc" #define USERSTARTPATH OS::getenv("HOME") #define STEPFILE "/tmp/SXXXXXX" #define SHELL OS::getenv("COMSPEC") /*--------------------------------------------------------------------------*/ #else #define ENDDIR "/" #define PATHSEP ':' #define SYSTEMSTARTFILE "gnucap.rc" #define SYSTEMSTARTPATH OS::getenv("PATH") #define USERSTARTFILE ".gnucaprc" #define USERSTARTPATH OS::getenv("HOME") #define STEPFILE "/tmp/SXXXXXX" #define SHELL OS::getenv("SHELL") #endif /*--------------------------------------------------------------------------*/ /* machine and compiler patches */ #if defined(__MINGW32__) #define SIGSETJMP_IS_BROKEN #define MS_DLL #endif /*--------------------------------------------------------------------------*/ /* some convenient names */ typedef std::complex COMPLEX; typedef std::pair DPAIR; /*--------------------------------------------------------------------------*/ // dynamic cast kluge. // Strictly, this should always be dynamic_cast, but if it has already // been checked, don't bother checking again, hence static_cast. // It works and is faster. #if defined(NDEBUG) #define prechecked_cast static_cast #else #define prechecked_cast dynamic_cast #endif /*--------------------------------------------------------------------------*/ /* portability hacks */ #if !defined(MS_DLL) // The usual way for POSIX compliant systems #include #define INTERFACE #else // Microsoft DLL hacks -- thanks to Holger Vogt and Cesar Strauss for the info // Make the MS DLL functions look like the posix ones. #include #undef min #undef max #undef INTERFACE #ifdef MAKE_DLL #define INTERFACE __declspec(dllimport) #else #define INTERFACE __declspec(dllexport) #endif inline void* dlopen(const char* f, int) { return LoadLibrary(const_cast(f)); } inline void dlclose(void* h) { FreeLibrary((HINSTANCE)h); } inline char* dlerror() { static LPVOID lpMsgBuf = NULL; // free the error message buffer if (lpMsgBuf) { LocalFree(lpMsgBuf); } // get the error code DWORD dw = GetLastError(); // get the corresponding error message FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); return (char*)lpMsgBuf; } #define RTLD_LAZY 0x00001 /* Lazy function call binding. */ #define RTLD_NOW 0x00002 /* Immediate function call binding. */ #define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */ #define RTLD_NOLOAD 0x00004 /* Do not load the object. */ #define RTLD_DEEPBIND 0x00008 /* Use deep binding. */ #define RTLD_GLOBAL 0x00100 #define RTLD_LOCAL 0 #define RTLD_NODELETE 0x01000 #endif #if defined(SIGSETJMP_IS_BROKEN) #undef sigjmp_buf #undef siglongjmp #undef sigsetjmp #define sigjmp_buf jmp_buf #define siglongjmp(a,b) longjmp(a,b) #define sigsetjmp(a,b) setjmp(a) #endif #if !defined(SIGNALARGS) #define SIGNALARGS int #endif /*--------------------------------------------------------------------------*/ /* temporary hacks */ enum RUN_MODE { rPRE_MAIN, /* it hasn't got to main yet */ rPRESET, /* do set up commands now, but not simulation */ /* store parameters, so bare invocation of a */ /* simulation command will do it this way. */ rINTERACTIVE, /* run the commands, interactively */ rSCRIPT, /* execute now, as a command, then restore mode */ rBATCH /* execute now, as a command, then exit */ }; class INTERFACE ENV { public: static RUN_MODE run_mode; // variations on handling of dot commands }; /*--------------------------------------------------------------------------*/ /* my standard collection of includes */ #include "io_trace.h" #include "io_error.h" /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif modelgen/mg_.h000066400000000000000000000473741145401216200135760ustar00rootroot00000000000000/*$Id: mg_.h,v 26.81 2008/05/27 05:33:43 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script 2006.10.31 #include #include "md.h" #include "ap.h" /*--------------------------------------------------------------------------*/ // defined here class Base; class C_Comment; class Cxx_Comment; class Parameter; class Code_Block; class Parameter_Block; class String_Arg; class Model; class Head; class File; /*--------------------------------------------------------------------------*/ // external class CS; /*--------------------------------------------------------------------------*/ #ifdef PASS_TRACE_TAGS #define make_tag() (out << "//" << __func__ << ":" << __LINE__ << "\n") #else #define make_tag() #endif /*--------------------------------------------------------------------------*/ inline std::string to_lower(std::string s) { for (std::string::iterator i = s.begin(); i != s.end(); ++i) { *i = static_cast(tolower(*i)); } return s; } /*--------------------------------------------------------------------------*/ inline std::string to_upper(std::string s) { for (std::string::iterator i = s.begin(); i != s.end(); ++i) { *i = static_cast(toupper(*i)); } return s; } /*--------------------------------------------------------------------------*/ inline void error(const std::string& message) {untested(); std::cerr << message << '\n'; exit(1); } /*--------------------------------------------------------------------------*/ inline void os_error(const std::string& name) {untested(); error(name + ':' + strerror(errno)); } /*--------------------------------------------------------------------------*/ class Base { public: virtual void parse(CS&) = 0; virtual void print(std::ostream& f)const {unreachable(); f << "Base::print";} virtual ~Base() {} }; inline CS& operator>>(CS& f, Base& b) {untested();b.parse(f); return f;} inline std::ostream& operator<<(std::ostream& f, const Base& d) {d.print(f); return f;} /*--------------------------------------------------------------------------*/ template class List_Base :public Base { protected: typedef typename std::list _Std_List_T; _Std_List_T _list; virtual ~List_Base() { for (typename std::list::iterator i = _list.begin(); i != _list.end(); ++i) { delete *i; } } public: virtual void parse(CS& f) = 0; typedef typename std::list::const_iterator const_iterator; const_iterator begin()const {return _list.begin();} const_iterator end()const {return _list.end();} bool is_empty()const {return _list.empty();} size_t size()const {return _list.size();} }; /*--------------------------------------------------------------------------*/ /* A "Collection" differs from a "List" in how it is parsed. * Each parse of a "Collection" created one more object and stores * it in the Collection. The size of the Collection therefore grows by 1. * A "Collection" is often parsed many times. * Each parse of a "List" creates a bunch of objects, and storing them. * A list has opening and closing delimeters, usually {}. * A "List" is usually parsed once. */ template class List :public List_Base { using List_Base::_list; public: //BUG// why not inherited? typedef typename std::list::const_iterator const_iterator; const_iterator begin()const {return _list.begin();} const_iterator end()const {return _list.end();} void parse(CS& file) { int paren = !BEGIN || file.skip1b(BEGIN); unsigned here = file.cursor(); for (;;) { C_Comment c_comment; Cxx_Comment cxx_comment; (file >> "/*") && (file >> c_comment); (file >> "//") && (file >> cxx_comment); if (file.stuck(&here)) { paren -= file.skip1b(END); if (paren == 0) { //file.warn(0, "list exit"); break; }else{ //file.warn(0, "list"); } T* p = new T(file); if (!file.stuck(&here)) { _list.push_back(p); }else{itested(); delete p; file.warn(0, "not valid here"); break; } }else{ } } } void print(std::ostream& f)const { f << BEGIN; for (const_iterator i = begin(); i != end(); ++i) { f << (**i); } f << END; } }; /*--------------------------------------------------------------------------*/ /* A "Collection" differs from a "List" in how it is parsed. * Each parse of a "Collection" created one more object and stores * it in the Collection. The size of the Collection therefore grows by 1. * A "Collection" is often parsed many times. * Each parse of a "List" creates a bunch of objects, and storing them. * A list has opening and closing delimeters, usually {}. * A "List" is usually parsed once. */ template class Collection :public List_Base { using List_Base::_list; public: //BUG// why not inherited? typedef typename std::list::const_iterator const_iterator; const_iterator begin()const {return _list.begin();} const_iterator end()const {return _list.end();} void parse(CS& file) { unsigned here = file.cursor(); T* m = new T(file); if (!file.stuck(&here)) { _list.push_back(m); }else{untested(); delete m; file.warn(0, "what's this??"); } } void print(std::ostream& f)const { for (const_iterator i = begin(); i != end(); ++i) { f << (**i); } } }; /*--------------------------------------------------------------------------*/ class C_Comment :public Base { public: void parse(CS& f); }; /*--------------------------------------------------------------------------*/ class Cxx_Comment :public Base { public: void parse(CS& f); }; /*--------------------------------------------------------------------------*/ class Key :public Base { std::string _name; std::string _var; std::string _value; public: void parse(CS& f) {f >> _name >> _var >> '=' >> _value >> ';';} void print(std::ostream& f)const {f << name() << " " << var() << "=" << value() << "; ";} Key(CS& f) {parse(f);} const std::string& name()const {return _name;} const std::string& var()const {return _var;} const std::string& value()const {return _value;} }; typedef List Key_List; /*--------------------------------------------------------------------------*/ class String_Arg :public Base { std::string _s; public: void parse(CS& f) {f >> _s >> ';';} void print(std::ostream& f)const {f << _s;} void operator=(const std::string& s) {untested();_s = s;} void operator+=(const std::string& s) {_s += s;} bool operator!=(const std::string& s)const {return _s != s;} bool is_empty()const {return _s.empty();} std::string lower()const {return to_lower(_s);} const std::string& to_string()const {return _s;} }; /*--------------------------------------------------------------------------*/ class Bool_Arg :public Base { bool _s; public: void parse(CS& f) {_s = true; f.skip1b(";");} void print(std::ostream& f)const {untested();f << _s;} Bool_Arg() :_s(false) {} operator bool()const {return _s;} }; /*--------------------------------------------------------------------------*/ class Parameter :public Base { std::string _type; std::string _code_name; std::string _user_name; std::string _alt_name; std::string _default_val; std::string _comment; std::string _print_test; std::string _calc_print_test; std::string _scale; std::string _offset; std::string _calculate; std::string _quiet_min; std::string _quiet_max; std::string _final_default; bool _positive; bool _octal; public: void parse(CS& f); void print(std::ostream& f)const; Parameter(CS& f) :_positive(false), _octal(false) {parse(f);} const std::string& type()const {return _type;} const std::string& code_name()const {return _code_name;} const std::string& user_name()const {return _user_name;} const std::string& alt_name()const {return _alt_name;} const std::string& comment()const {return _comment;} const std::string& default_val()const {return _default_val;} const std::string& print_test()const {return _print_test;} const std::string& calc_print_test()const {return _calc_print_test;} const std::string& scale()const {return _scale;} const std::string& offset()const {return _offset;} const std::string& calculate()const {return _calculate;} const std::string& quiet_min()const {return _quiet_min;} const std::string& quiet_max()const {return _quiet_max;} const std::string& final_default()const {return _final_default;} bool positive()const {return _positive;} bool octal()const {return _octal;} void fill_in_default_name() { if (_user_name.empty()) { _user_name = to_upper(_code_name); }else{ } } }; typedef List Parameter_List; /*--------------------------------------------------------------------------*/ class Code_Block :public Base { std::string s; public: void parse(CS& f); void print(std::ostream& f)const {f << s;} Code_Block() {} bool is_empty()const {return s.length() < 2;} }; /*--------------------------------------------------------------------------*/ class Parameter_Block :public Base { String_Arg _unnamed_value; Parameter_List _override; Parameter_List _raw; Parameter_List _calculated; Code_Block _code_pre; Code_Block _code_mid; Code_Block _code_post; public: void parse(CS& f); void print(std::ostream& f)const; const String_Arg& unnamed_value()const {return _unnamed_value;} const Parameter_List& override()const {return _override;} const Parameter_List& raw()const {return _raw;} const Parameter_List& calculated()const {return _calculated;} const Code_Block& code_pre()const {return _code_pre;} const Code_Block& code_mid()const {return _code_mid;} const Code_Block& code_post()const {return _code_post;} bool is_empty()const {return (calculated().is_empty() && code_post().is_empty() && code_mid().is_empty() && override().is_empty() && raw().is_empty() && code_pre().is_empty());} void fill_in_default_values(); }; /*--------------------------------------------------------------------------*/ class Eval :public Base { protected: String_Arg _name; Code_Block _code; Eval() :_name(), _code() {} public: void parse(CS& f); void print(std::ostream& f)const; Eval(CS& f) :_name(), _code() {parse(f);} const String_Arg& name()const {return _name;} const Code_Block& code()const {return _code;} }; typedef Collection Eval_List; /*--------------------------------------------------------------------------*/ class Function :public Eval { public: void parse(CS& f); void print(std::ostream& f)const; Function(CS& f) :Eval() {parse(f);} }; typedef Collection Function_List; /*--------------------------------------------------------------------------*/ class Port :public Base { std::string _name; std::string _short_to; std::string _short_if; public: void parse(CS& f); void print(std::ostream& f)const; Port() {untested();} Port(CS& f) {parse(f);} const std::string& name()const {return _name;} const std::string& short_to()const {return _short_to;} const std::string& short_if()const {return _short_if;} }; typedef List Port_List; /*--------------------------------------------------------------------------*/ class Element :public Base { std::string _dev_type; std::string _name; Port_List _port_list; std::string _eval; std::string _value; std::string _args; std::string _omit; std::string _reverse; std::string _state; public: void parse(CS&); void print(std::ostream& f)const; Element() {untested();} Element(CS& f) {parse(f);} const std::string& dev_type()const {return _dev_type;} const Port_List& ports()const {return _port_list;} const std::string& name()const {return _name;} const std::string& eval()const {return _eval;} const std::string& value()const {return _value;} const std::string& args()const {return _args;} const std::string& omit()const {return _omit;} const std::string& reverse()const {return _reverse;} const std::string& state()const {return _state;} size_t num_nodes()const {return ports().size();} }; typedef Collection Element_List; /*--------------------------------------------------------------------------*/ class Arg :public Base { std::string _arg; public: void parse(CS& f); void print(std::ostream& f)const {f << " " << arg() << ";\n";} Arg(CS& f) {parse(f);} const std::string& arg()const {return _arg;} }; typedef List Arg_List; /*--------------------------------------------------------------------------*/ class Args :public Base { String_Arg _name; String_Arg _type; Arg_List _arg_list; public: void parse(CS& f) {f >> _name >> _type >> _arg_list;} void print(std::ostream& f)const {f << " args " << name() << " " << type() << "\n" << arg_list() << "\n";} Args(CS& f) {parse(f);} const String_Arg& name()const {return _name;} const String_Arg& type()const {return _type;} const Arg_List& arg_list()const {return _arg_list;} typedef Arg_List::const_iterator const_iterator; const_iterator begin()const {return _arg_list.begin();} const_iterator end()const {return _arg_list.end();} }; typedef Collection Args_List; /*--------------------------------------------------------------------------*/ class Circuit :public Base { Port_List _required_nodes; Port_List _optional_nodes; Port_List _local_nodes; Element_List _element_list; Args_List _args_list; bool _sync; public: void parse(CS&); void print(std::ostream& f)const; Circuit() : _sync(false) {} bool sync()const {return _sync;} const Port_List& req_nodes()const {return _required_nodes;} const Port_List& opt_nodes()const {return _optional_nodes;} const Port_List& local_nodes()const {return _local_nodes;} const Element_List& elements()const {return _element_list;} const Args_List& args_list()const {return _args_list;} size_t min_nodes()const {return req_nodes().size();} size_t max_nodes()const {return opt_nodes().size()+min_nodes();} size_t net_nodes()const {untested();return max_nodes();} }; /*--------------------------------------------------------------------------*/ class Probe :public Base { std::string _name; std::string _expression; public: void parse(CS& f) {f >> _name >> '=' >> _expression >> ';';} void print(std::ostream& f)const {f << " " << name() << " = \"" << expression() << "\";\n";} Probe() {untested();} Probe(CS& f) {parse(f);} const std::string& name()const {return _name;} const std::string& expression()const {return _expression;} }; typedef List Probe_List; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ class Model :public Base { String_Arg _name; String_Arg _level; String_Arg _dev_type; String_Arg _inherit; Key_List _public_key_list; Key_List _private_key_list; Parameter_Block _independent; Parameter_Block _size_dependent; Parameter_Block _temperature; Code_Block _tr_eval; Code_Block _validate; Bool_Arg _hide_base; public: void parse(CS& f); void print(std::ostream& f)const; Model(CS& f) {parse(f);} bool hide_base()const {return _hide_base;} const String_Arg& name()const {return _name;} const String_Arg& level()const {return _level;} const String_Arg& dev_type()const {return _dev_type;} const String_Arg& inherit()const {return _inherit;} const Key_List& public_key_list()const {return _public_key_list;} const Key_List& private_key_list()const{return _private_key_list;} const Parameter_Block& independent()const {return _independent;} const Parameter_Block& size_dependent()const {return _size_dependent;} const Parameter_Block& temperature()const {return _temperature;} const Code_Block& tr_eval()const {return _tr_eval;} const Code_Block& validate()const {return _validate;} }; typedef Collection Model_List; /*--------------------------------------------------------------------------*/ class Device :public Base { String_Arg _name; String_Arg _parse_name; String_Arg _id_letter; String_Arg _model_type; Circuit _circuit; Probe_List _probes; Parameter_Block _device; Parameter_Block _common; Code_Block _tr_eval; Eval_List _eval_list; Function_List _function_list; public: void parse(CS& f); void print(std::ostream& f)const; Device(CS& f) {parse(f);} const String_Arg& name()const {return _name;} const String_Arg& parse_name()const {return _parse_name;} const String_Arg& id_letter()const {return _id_letter;} const String_Arg& model_type()const {return _model_type;} const Circuit& circuit()const {return _circuit;} const Probe_List& probes()const {return _probes;} const Parameter_Block& device()const {return _device;} const Parameter_Block& common()const {return _common;} const Code_Block& tr_eval()const {return _tr_eval;} const Eval_List& eval_list()const {return _eval_list;} const Function_List& function_list()const {return _function_list;} size_t min_nodes()const {return circuit().min_nodes();} size_t max_nodes()const {return circuit().max_nodes();} size_t net_nodes()const {untested();return circuit().net_nodes();} }; typedef Collection Device_List; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ class Head :public Base { std::string s; public: void parse(CS& f); void print(std::ostream& f)const {f << s;} Head() {} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ class Attribute :public Base { String_Arg _name; String_Arg _value; public: void parse(CS& f); Attribute(CS& f) {untested();parse(f);} const String_Arg& name()const {untested();return _name;} const String_Arg& value()const {untested();return _value;} }; typedef Collection Attribute_List; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ class File { std::string _name; CS _file; Head _head; Code_Block _h_headers; Code_Block _cc_headers; Model_List _model_list; Device_List _device_list; Code_Block _h_direct; Code_Block _cc_direct; public: File(const std::string& file_name); const std::string& name()const {return _name;} const Head& head()const {return _head;} const Code_Block& h_headers()const {return _h_headers;} const Code_Block& cc_headers()const {return _cc_headers;} const Model_List& models()const {return _model_list;} const Device_List& devices()const {return _device_list;} const Code_Block& h_direct()const {return _h_direct;} const Code_Block& cc_direct()const {return _cc_direct;} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/mg_error.cc000066400000000000000000000070401145401216200147700ustar00rootroot00000000000000/*$Id: mg_error.cc,v 26.81 2008/05/27 05:33:43 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Error handler. */ //testing=script,sparse 2006.10.31 #include "ap.h" extern int errorcount; /*--------------------------------------------------------------------------*/ void error(int, const std::string& message) {untested(); std::cout << message << '\n'; exit(2); } void error(int,const char* message,...) {untested(); std::cout << message << '\n'; exit(2); } /*--------------------------------------------------------------------------*/ /* syntax_check: handle syntax errors * called on parsing an input string when nothing else matches. * if the rest of the line is nothing, just return * if comment, increment *cnt, so what is left is a valid comment string * otherwise, it is an error (the arrow pointing at the offending word) */ CS & CS::check(int badness, const std::string& message) {untested(); skipbl(); switch (peek()) { case '\'': _ok = true; skip(); break; case '\0': _ok = true; break; default: _ok = false; warn(badness, message); break; } return *this; } /*--------------------------------------------------------------------------*/ static void tab(unsigned n) {itested(); for (unsigned i=0; i= 0) {itested(); ++errorcount; unsigned linestart = spot; for (;;) {itested(); if (linestart == 0) {untested(); break; }else if (_cmd[linestart] == '\n') {itested(); ++linestart; break; }else{itested(); --linestart; } } int lineno = 1; for (unsigned i=0; i * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script 2006.10.31 #include "mg_.h" /*--------------------------------------------------------------------------*/ static C_Comment dummy_c_comment; static Cxx_Comment dummy_cxx_comment; /*--------------------------------------------------------------------------*/ void Parameter::parse(CS& file) { file >> _type >> _code_name >> _comment; unsigned here = file.cursor(); for (;;) { ONE_OF || Set(file, "positive", &_positive, true) || Set(file, "octal", &_octal, true) || ((file >> "name =") && (file >> _user_name)) || ((file >> "alt_name =") && (file >> _alt_name)) || ((file >> "default =") && (file >> _default_val)) || ((file >> "offset =") && (file >> _offset)) || ((file >> "print_test =") && (file >> _print_test)) || ((file >> "calc_print_test =")&& (file >> _calc_print_test)) || ((file >> "scale =") && (file >> _scale)) || ((file >> "calculate =") && (file >> _calculate)) || ((file >> "quiet_min =") && (file >> _quiet_min)) || ((file >> "quiet_max =") && (file >> _quiet_max)) || ((file >> "final_default =") && (file >> _final_default)) || ((file >> "/*") && (file >> dummy_c_comment)) || ((file >> "//") && (file >> dummy_cxx_comment)) ; if (file.skip1b(";,")) { break; }else if (!file.more()) {untested(); file.warn(0, "premature EOF (parameter)"); break; }else if (file.stuck(&here)) {untested(); file.warn(0, "need ;"); break; }else{ } } } /*--------------------------------------------------------------------------*/ void Parameter::print(std::ostream& out)const { out << "\n" " " << type() << " " << code_name() << " \"" << comment() << "\"\n " "name=\"" << user_name() << "\" " "alt_name=\"" << alt_name() << "\" " "default=\"" << default_val() << "\" " "offset=\"" << offset() << "\"\n "; if (positive()) { out << "positive "; } if (octal()) { out << "octal "; } out << "print_test=\"" << print_test() << "\" " "calc_print_test=\"" << calc_print_test() << "\"\n " "scale=\"" << scale() << "\" " "calculate=\"" << calculate() << "\"\n " "quiet_min=\"" << quiet_min() << "\" " "quiet_max=\"" << quiet_max() << "\"\n " "final_default=\"" << final_default() << "\";"; } /*--------------------------------------------------------------------------*/ void Code_Block::parse(CS& file) { // skips the code block, delimited by {} // also checks paren balance, so you can have {} inside the block int paren = file.skip1("{"); if (paren == 0) {untested(); file.warn(0, "need {"); }else{ } unsigned here = file.cursor(); unsigned begin = here; unsigned end = here; for (;;) { paren -= file.skip1b("])"); if (paren == 0) {untested(); file.warn(0, "unbalanced {}[]()"); break; }else{ } end = file.cursor(); paren -= file.skip1b("}"); if (paren == 0) { unsigned ihere = file.cursor(); while (file.reset(--end).peek() != '\n' && end >= begin) { } ++end; file.reset(ihere); break; }else{ } if (file.stuck(&here)) {untested(); file.warn(0, "syntax error"); break; }else{ } paren += file.skip1b("{[("); file.skip1b(";="); std::string foo; file >> foo; } s = file.substr(begin, end - begin); } /*--------------------------------------------------------------------------*/ static void fill_in_default_names(Parameter_List& pl) { for (Parameter_List::const_iterator p = pl.begin(); p != pl.end(); ++p) { (**p).fill_in_default_name(); } } /*--------------------------------------------------------------------------*/ void Parameter_Block::parse(CS& file) { int paren = file.skip1b("{"); unsigned here = file.cursor(); for (;;) { ONE_OF || ((file >> "unnamed ") && (file >> _unnamed_value)) || ((file >> "override ") && (file >> _override)) || ((file >> "raw_parameters ") && (file >> _raw)) || ((file >> "calculated_parameters ")&& (file >> _calculated)) || ((file >> "code_pre ") && (file >> _code_pre)) || ((file >> "code_mid ") && (file >> _code_mid)) || ((file >> "code_post ") && (file >> _code_post)) || ((file >> "/*") && (file >> dummy_c_comment)) || ((file >> "//") && (file >> dummy_cxx_comment)) ; paren -= file.skip1b("}"); if (paren == 0) { break; }else if (!file.more()) {untested(); file.warn(0, "premature EOF (Parameter_Block)"); break; }else if (file.stuck(&here)) {itested(); file.warn(0, "bad Parameter_Code_Block"); break; }else{ } } fill_in_default_names(_calculated); fill_in_default_names(_raw); // but not _override } /*--------------------------------------------------------------------------*/ void Parameter_Block::print(std::ostream& out)const { out << "{\n"; if (unnamed_value() != "") { out << " unnamed " << unnamed_value() << ";\n"; } out << " override " << override() << "\n" " raw_parameters " << raw() << "\n" " calculated_parameters " << calculated() << "\n" " code_pre {" << code_pre() << " }\n" " code_mid {" << code_mid() << " }\n" " code_post {" << code_post() << " }\n" " }\n"; } /*--------------------------------------------------------------------------*/ void Eval::parse(CS& file) { file >> _name >> _code; } /*--------------------------------------------------------------------------*/ void Eval::print(std::ostream& out)const { out << " eval " << name() << " {" << code() << " }\n"; } /*--------------------------------------------------------------------------*/ void Function::parse(CS& file) { file >> _name; _name += '(' + file.ctos("{", "(", ")") + ')'; file >> _code; } /*--------------------------------------------------------------------------*/ void Function::print(std::ostream& out)const { out << " function " << name() << " {" << code() << " }\n"; } /*--------------------------------------------------------------------------*/ void Element::parse(CS& file) { file >> _dev_type >> _name >> _port_list; unsigned here = file.cursor(); for (;;) { ONE_OF || ((file >> "eval =") && (file >> _eval)) || ((file >> "value =") && (file >> _value)) || ((file >> "args =") && (file >> _args)) || ((file >> "omit =") && (file >> _omit)) || ((file >> "reverse =") && (file >> _reverse)) || ((file >> "state =") && (file >> _state)) || ((file >> "/*") && (file >> dummy_c_comment)) || ((file >> "//") && (file >> dummy_cxx_comment)) ; if (file.skip1b(";")) { break; }else if (!file.more()) {untested(); file.warn(0, "premature EOF (Element)"); break; }else if (file.stuck(&here)) {untested(); file.warn(0, "need ;"); break; }else{ } } } /*--------------------------------------------------------------------------*/ void Element::print(std::ostream& out)const { out << " " << dev_type() << " " << name() << " " << ports(); if (eval() != "") { out << " eval=\"" << eval() << "\""; } if (value() != "") { out << " value=\"" << value() << "\""; } if (args() != "") { out << " args=\"" << args() << "\""; } if (omit() != "") { out << " omit=\"" << omit() << "\""; } if (reverse() != "") { out << " reverse=\"" << reverse() << "\""; } if (state() != "") { out << " state=\"" << state() << "\""; } out << ";\n"; } /*--------------------------------------------------------------------------*/ void Arg::parse(CS& file) { file.skipbl(); _arg = file.get_to(";"); file.skip1b(";"); } /*--------------------------------------------------------------------------*/ void Circuit::parse(CS& file) { int paren = file.skip1b("{"); (file >> "/*") && (file >> dummy_c_comment); (file >> "//") && (file >> dummy_cxx_comment); (file >> "sync ;") && (_sync = true); (file >> "ports ") && ((file >> _required_nodes >> _optional_nodes >> ';') || file.warn(0, "need ports")); (file >> "local_nodes ") && (file >> _local_nodes >> ';'); unsigned here = file.cursor(); do { (file >> "args ") && (file >> _args_list); } while (file.more() && !file.stuck(&here)); for (;;) { paren -= file.skip1b("}"); if (paren == 0) { break; }else if (!file.more()) {untested(); file.warn(0, "premature EOF (Circuit)"); break; }else{ } ONE_OF || ((file >> "/*") && (file >> dummy_c_comment)) || ((file >> "//") && (file >> dummy_cxx_comment)) || (file >> _element_list) ; if (file.stuck(&here)) {untested(); file.warn(0, "bad Circuit"); break; }else{ } } } /*--------------------------------------------------------------------------*/ void Circuit::print(std::ostream& out)const { out << " {\n"; if (sync()) { out << " sync;\n"; } out << " ports " << req_nodes() << opt_nodes() << ";\n" " local_nodes " << local_nodes() << "\n" << args_list() << elements() << "}\n"; } /*--------------------------------------------------------------------------*/ void Model::parse(CS& file) { file >> _name; int paren = file.skip1b("{"); unsigned here = file.cursor(); for (;;) { ONE_OF || ((file >> "hide_base ") && (file >> _hide_base)) || ((file >> "level ") && (file >> _level)) || ((file >> "dev_type ") && (file >> _dev_type)) || ((file >> "inherit ") && (file >> _inherit)) || ((file >> "public_keys ") && (file >> _public_key_list)) || ((file >> "private_keys ") && (file >> _private_key_list)) || ((file >> "independent ") && (file >> _independent)) || ((file >> "size_dependent ") && (file >> _size_dependent)) || ((file >> "temperature_dependent ") && (file >> _temperature)) || ((file >> "tr_eval ") && (file >> _tr_eval)) || ((file >> "validate ") && (file >> _validate)) || ((file >> "/*") && (file >> dummy_c_comment)) || ((file >> "//") && (file >> dummy_cxx_comment)) ; paren -= file.skip1b("}"); if (paren == 0) { break; }else if (!file.more()) {untested(); file.warn(0, "premature EOF (Model)"); break; }else if (file.stuck(&here)) {itested(); file.warn(0, "bad Model"); break; }else{ } } } /*--------------------------------------------------------------------------*/ void Model::print(std::ostream& out)const { out << "model " << name() << " {\n"; if (hide_base()) { out << " hide_base;\n"; } out << " level = " << level() << ";\n" " dev_type = " << dev_type() << ";\n" " inherit = " << inherit() << ";\n" " public_keys " << public_key_list() << "\n" " private_keys " << private_key_list() << "\n" " independent " << independent() << "\n" " size_dependent " << size_dependent() << "\n" " temperature_dependent " << temperature() << "\n" " tr_eval {" << tr_eval() << " }\n" " validate {" << validate() << " }\n" "}\n"; } /*--------------------------------------------------------------------------*/ void Device::parse(CS& file) { file >> _name; int paren = file.skip1b("{"); unsigned here = file.cursor(); for (;;) { ONE_OF || ((file >> "parse_name ") && (file >> _parse_name)) || ((file >> "id_letter ") && (file >> _id_letter)) || ((file >> "model_type ") && (file >> _model_type)) || ((file >> "circuit ") && (file >> _circuit)) || ((file >> "tr_probe ") && (file >> _probes)) || ((file >> "device ") && (file >> _device)) || ((file >> "common ") && (file >> _common)) || ((file >> "tr_eval ") && (file >> _tr_eval)) || ((file >> "eval ") && (file >> _eval_list)) || ((file >> "function ") && (file >> _function_list)) || ((file >> "/*") && (file >> dummy_c_comment)) || ((file >> "//") && (file >> dummy_cxx_comment)) ; paren -= file.skip1b("}"); if (paren == 0) { break; }else if (!file.more()) {untested(); file.warn(0, "premature EOF (Device)"); break; }else if (file.stuck(&here)) {itested(); file.warn(0, "bad Device"); break; }else{ } } } /*--------------------------------------------------------------------------*/ void Device::print(std::ostream& out)const { out << "device " << name() << " {\n" " parse_name " << parse_name() << ";\n" " id_letter " << id_letter() << ";\n" " model_type " << model_type() << ";\n" " circuit " << circuit() << "\n" " tr_probe " << probes() << "\n" " device " << device() << "\n" " common " << common() << "\n" " tr_eval {" << tr_eval() << " }\n" << eval_list() << function_list() << "}\n"; } /*--------------------------------------------------------------------------*/ void C_Comment::parse(CS& file) { unsigned here = file.cursor(); for (;;) { file.skipto1('*'); if (file.umatch("*/")) { break; // done with comment }else if (file.stuck(&here)) {untested(); file.warn(0, "unterminated C comment"); break; }else{untested(); file.skip(); } } } /*--------------------------------------------------------------------------*/ void Cxx_Comment::parse(CS& file) { unsigned here = file.cursor(); file.skipto1('\n'); if (file.stuck(&here)) {untested(); file.warn(0, "unterminated C++ comment"); }else{ } } /*--------------------------------------------------------------------------*/ void Port::parse(CS& file) { file >> _name; unsigned here = file.cursor(); for (;;) { ONE_OF || ((file >> "short_to =") && (file >> _short_to)) || ((file >> "short_if =") && (file >> _short_if)) ; if (file.skip1b(";")) { break; }else if (!file.more()) {untested(); file.warn(0, "premature EOF (Port)"); break; }else if (file.stuck(&here)) { break; }else{ } } } /*--------------------------------------------------------------------------*/ void Port::print(std::ostream& out)const { if (short_to() != "" || short_if() != "") { out << name() << " short_to=\"" << short_to() << "\" short_if=\"" << short_if() << "\";\n"; }else{ out << name() << "; "; } } /*--------------------------------------------------------------------------*/ void Head::parse(CS& file) { unsigned here = file.cursor(); unsigned begin = 0; unsigned end = here; for (;;) { file.skipto1('*'); if (file.umatch("*/")) { end = file.cursor(); break; // done with head }else if (file.stuck(&here)) {untested(); file.warn(0, "unterminated head"); break; }else{ file.skip(); } } s = file.substr(begin, end-begin); } /*--------------------------------------------------------------------------*/ File::File(const std::string& file_name) :_name(file_name), _file(CS::_WHOLE_FILE, file_name) { (_file >> "/*") && (_file >> _head); unsigned here = _file.cursor(); for (;;) { ONE_OF || ((_file >> "/*") && (_file >> dummy_c_comment)) || ((_file >> "//") && (_file >> dummy_cxx_comment)) || ((_file >> "h_headers ") && (_file >> _h_headers)) || ((_file >> "cc_headers ")&& (_file >> _cc_headers)) || ((_file >> "device ") && (_file >> _device_list)) || ((_file >> "model ") && (_file >> _model_list)) || ((_file >> "h_direct ") && (_file >> _h_direct)) || ((_file >> "cc_direct ") && (_file >> _cc_direct)) ; if (!_file.more()) { break; }else if (_file.stuck(&here)) {itested(); _file.warn(0, "syntax error, need head or model"); break; }else{ } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/mg_main.cc000066400000000000000000000050611145401216200145640ustar00rootroot00000000000000/*$Id: mg_main.cc,v 26.81 2008/05/27 05:33:43 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script 2006.11.01 #include "u_opt.h" #include "mg_out.h" #include "patchlev.h" /*global*/ int errorcount = 0; RUN_MODE ENV::run_mode = rPRE_MAIN; /*--------------------------------------------------------------------------*/ int main(int argc, char** argv) { try { if (argc > 2 && strcmp(argv[1],"-h")==0) { for (int i=2; i 2 && strcmp(argv[1],"-cc")==0) { for (int i=2; i 2 && strcmp(argv[1],"-dump")==0) { for (int i=2; i 2 && strcmp(argv[1],"-v")==0) {untested(); std::cerr << "Gnucap model compiler " PATCHLEVEL "\n" "Part of the Gnu Circuit Analysis Package\n" "Never trust any version less than 1.0\n" " or any version with a number that looks like a date.\n" "Copyright 2001-2003, Albert Davis\n" "Gnucap comes with ABSOLUTELY NO WARRANTY\n" "This is free software, and you are welcome\n" "to redistribute it under certain conditions\n" "according to the GNU General Public License.\n" "See the file \"COPYING\" for details.\n"; }else if (argc > 1) {itested(); for (int i=1; i * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include #include "mg_.h" /*--------------------------------------------------------------------------*/ /* mg_out_root.cc */ void make_h_file(const File&); void make_cc_file(const File&); void make_dump_file(const File&); /*--------------------------------------------------------------------------*/ /* mg_out_lib.cc */ void make_final_adjust_eval_parameter_list(std::ofstream&, const Parameter_List&); void make_final_adjust_value(std::ofstream&, const Parameter&); void make_final_adjust_value_list(std::ofstream&, const Parameter_List&); void make_final_adjust_parameter(std::ofstream&, const Parameter&); void make_final_adjust_parameter_list(std::ofstream&, const Parameter_List&); void make_final_adjust(std::ofstream&, const Parameter_Block&); void make_construct_parameter_list(std::ofstream&, const Parameter_List&); void make_get_param_list(std::ofstream&, const Parameter_List&); void make_print_param_list(std::ofstream&, const Parameter_List&); void make_print_calc_param_list(std::ofstream&, const Parameter_List&); void make_copy_construct_parameter_list(std::ofstream&, const Parameter_List&); /*--------------------------------------------------------------------------*/ /* mg_out_model.cc */ void make_cc_model(std::ofstream&, const Model&); /* mg_out_dev.cc */ void make_cc_dev(std::ofstream&, const Device&); /* mg_out_common.cc */ void make_cc_common(std::ofstream&, const Device&); /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/mg_out_common.cc000066400000000000000000000360431145401216200160230ustar00rootroot00000000000000/*$Id: mg_out_common.cc,v 26.130 2009/11/15 21:51:08 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script 2006.11.01 #include "mg_out.h" /*--------------------------------------------------------------------------*/ static void make_common_default_constructor(std::ofstream& out,const Device& d) { make_tag(); out << "COMMON_" << d.name() << "::COMMON_" << d.name() << "(int c)\n" " :COMMON_COMPONENT(c)"; make_construct_parameter_list(out, d.common().raw()); out << ",\n _sdp(0)"; make_construct_parameter_list(out, d.common().calculated()); for (Args_List::const_iterator p = d.circuit().args_list().begin(); p != d.circuit().args_list().end(); ++p) { out << ",\n _" << (**p).name() << "(0)"; } out << "\n" "{\n" " ++_count;\n"; for (Parameter_List::const_iterator p = d.common().override().begin(); p != d.common().override().end(); ++p) {untested(); if (!((**p).final_default().empty())) {untested(); out << " " << (**p).code_name() << " = NA;\n"; }else{untested(); } if (!((**p).default_val().empty())) {untested(); out << " " << (**p).code_name() << " = " << (**p).default_val() <<";\n"; }else{untested(); } } out << "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_common_copy_constructor(std::ofstream& out, const Device& d) { make_tag(); out << "COMMON_" << d.name() << "::COMMON_" << d.name() << "(const COMMON_" << d.name() << "& p)\n" " :COMMON_COMPONENT(p)"; make_copy_construct_parameter_list(out, d.common().raw()); out << ",\n _sdp(0)"; make_copy_construct_parameter_list(out, d.common().calculated()); for (Args_List::const_iterator p = d.circuit().args_list().begin(); p != d.circuit().args_list().end(); ++p) { out << ",\n _" << (**p).name() << "(0)"; } out << "\n" "{\n" " ++_count;\n"; for (Parameter_List::const_iterator p = d.common().override().begin(); p != d.common().override().end(); ++p) {untested(); out << ",\n " << (**p).code_name() << "(p." << (**p).code_name() << ")"; } out << "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_common_destructor(std::ofstream& out, const Device& d) { make_tag(); out << "COMMON_" << d.name() << "::~COMMON_" << d.name() << "()\n" "{\n"; for (Args_List::const_iterator p = d.circuit().args_list().begin(); p != d.circuit().args_list().end(); ++p) { out << " detach_common(&_" << (**p).name() << ");\n"; } out << " --_count;\n" " delete _sdp;\n" "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_common_operator_equal(std::ofstream& out, const Device& d) { make_tag(); out << "bool COMMON_" << d.name() << "::operator==(const COMMON_COMPONENT& x)const\n" "{\n" " const COMMON_" << d.name() << "* p = dynamic_cast(&x);\n" " return (p\n"; for (Parameter_List::const_iterator p = d.common().raw().begin(); p != d.common().raw().end(); ++p) { out << " && " << (**p).code_name() << " == p->" << (**p).code_name() << '\n'; } out << " && _sdp == p->_sdp\n" " && COMMON_COMPONENT::operator==(x));\n" "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ void make_common_set_param_by_index(std::ofstream& out, const Device& d) { make_tag(); out << "void COMMON_" << d.name() << "::set_param_by_index(int I, std::string& Value, int Offset)\n" "{\n" " switch (COMMON_" << d.name() << "::param_count() - 1 - I) {\n"; size_t i = 0; for (Parameter_List::const_iterator p = d.common().override().begin(); p != d.common().override().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": " << (**p).code_name() << " = Value; break;\n"; }else{unreachable(); } } assert(i == d.common().override().size()); for (Parameter_List::const_iterator p = d.common().raw().begin(); p != d.common().raw().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": " << (**p).code_name() << " = Value; break;\n"; }else{unreachable(); } } assert(i == d.common().override().size() + d.common().raw().size()); out << " default: COMMON_COMPONENT::set_param_by_index(I, Value, Offset);\n" " }\n" "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ void make_common_param_is_printable(std::ofstream& out, const Device& d) { make_tag(); out << "bool COMMON_" << d.name() << "::param_is_printable(int i)const\n" "{\n" " switch (COMMON_" << d.name() << "::param_count() - 1 - i) {\n"; size_t i = 0; for (Parameter_List::const_iterator p = d.common().override().begin(); p != d.common().override().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": return ("; if (!((**p).print_test().empty())) { out << (**p).print_test() << ");\n"; }else if ((**p).default_val() == "NA") { out << (**p).code_name() << " != NA);\n"; }else{ out << "true);\n"; } }else{unreachable(); } } assert(i == d.common().override().size()); for (Parameter_List::const_iterator p = d.common().raw().begin(); p != d.common().raw().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": return ("; if (!((**p).print_test().empty())) { out << (**p).print_test() << ");\n"; }else if ((**p).default_val() == "NA") { out << (**p).code_name() << " != NA);\n"; }else{ out << "true);\n"; } }else{unreachable(); } } assert(i == d.common().override().size() + d.common().raw().size()); out << " default: return COMMON_COMPONENT::param_is_printable(i);\n" " }\n" "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ void make_common_param_name(std::ofstream& out, const Device& d) { make_tag(); out << "std::string COMMON_" << d.name() << "::param_name(int i)const\n" "{\n" " switch (COMMON_" << d.name() << "::param_count() - 1 - i) {\n"; size_t i = 0; for (Parameter_List::const_iterator p = d.common().override().begin(); p != d.common().override().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": return \"" << to_lower((**p).user_name()) << "\";\n"; }else{unreachable(); } } assert(i == d.common().override().size()); for (Parameter_List::const_iterator p = d.common().raw().begin(); p != d.common().raw().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": return \"" << to_lower((**p).user_name()) << "\";\n"; }else{unreachable(); } } assert(i == d.common().override().size() + d.common().raw().size()); out << " default: return COMMON_COMPONENT::param_name(i);\n" " }\n" "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ void make_common_param_name_or_alias(std::ofstream& out, const Device& d) { make_tag(); out << "std::string COMMON_" << d.name() << "::param_name(int i, int j)const\n" "{\n" " if (j == 0) {\n" " return param_name(i);\n" " }else if (j == 1) {\n" " switch (COMMON_" << d.name() << "::param_count() - 1 - i) {\n"; size_t i = 0; for (Parameter_List::const_iterator p = d.common().override().begin(); p != d.common().override().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": return \"" << to_lower((**p).alt_name()) << "\";\n"; }else{unreachable(); } } assert(i == d.common().override().size()); for (Parameter_List::const_iterator p = d.common().raw().begin(); p != d.common().raw().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": return \"" << to_lower((**p).alt_name()) << "\";\n"; }else{unreachable(); } } assert(i == d.common().override().size() + d.common().raw().size()); out << " default: return \"\";\n" " }\n" " }else{untested();//281\n" " return COMMON_COMPONENT::param_name(i, j);\n" " }\n" "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ void make_common_param_value(std::ofstream& out, const Device& d) { make_tag(); out << "std::string COMMON_" << d.name() << "::param_value(int i)const\n" "{\n" " switch (COMMON_" << d.name() << "::param_count() - 1 - i) {\n"; size_t i = 0; for (Parameter_List::const_iterator p = d.common().override().begin(); p != d.common().override().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": return " << (**p).code_name() << ".string();\n"; }else{unreachable(); } } assert(i == d.common().override().size()); for (Parameter_List::const_iterator p = d.common().raw().begin(); p != d.common().raw().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": return " << (**p).code_name() << ".string();\n"; }else{unreachable(); } } assert(i == d.common().override().size() + d.common().raw().size()); out << " default: return COMMON_COMPONENT::param_value(i);\n" " }\n" "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_common_expand(std::ofstream& out, const Device& d) { make_tag(); out << "void COMMON_" << d.name() << "::expand(const COMPONENT* d)\n" "{\n" " COMMON_COMPONENT::expand(d);\n" " attach_model(d);\n" " COMMON_" << d.name() << "* c = this;\n" " const MODEL_" << d.model_type() << "* m = dynamic_cast(model());\n" " if (!m) {\n" " throw Exception_Model_Type_Mismatch(d->long_label(), modelname(), \"" << d.parse_name() << "\");\n" " }else{\n" " }\n" " // size dependent\n" " //delete _sdp;\n" " _sdp = m->new_sdp(this);\n" " assert(_sdp);\n" " const SDP_" << d.model_type() << "* s = prechecked_cast(_sdp);\n" " assert(s);\n" "\n" " // subcircuit commons, recursive\n"; for (Args_List::const_iterator p = d.circuit().args_list().begin(); p != d.circuit().args_list().end(); ++p) { out << " COMMON_" << (**p).type() << "* " << (**p).name() << " = new COMMON_" << (**p).type() << ";\n"; for (Arg_List::const_iterator a = (**p).begin(); a != (**p).end(); ++a) { out << " " << (**p).name() << "->" << (**a).arg() << ";\n"; } out << " attach_common(" << (**p).name() << ", &_" << (**p).name() << ");\n\n"; } out << " assert(c == this);\n" "}\n" "/*--------------------------------------------------------------------------*/\n" "void COMMON_" << d.name() << "::precalc_first(const CARD_LIST* par_scope)\n" "{\n" " assert(par_scope);\n" " COMMON_COMPONENT::precalc_first(par_scope);\n"; make_final_adjust_eval_parameter_list(out, d.common().raw()); out << "}\n" "/*--------------------------------------------------------------------------*/\n" "void COMMON_" << d.name() << "::precalc_last(const CARD_LIST* par_scope)\n" "{\n" " assert(par_scope);\n" " COMMON_COMPONENT::precalc_last(par_scope);\n" " COMMON_" << d.name() << "* c = this;\n" " const MODEL_" << d.model_type() << "* m = prechecked_cast(model());\n"; make_final_adjust(out, d.common()); out << "\n" " // size dependent\n" " //delete _sdp;\n" " _sdp = m->new_sdp(this);\n" " assert(_sdp);\n" " const SDP_" << d.model_type() << "* s = prechecked_cast(_sdp);\n" " assert(s);\n" "\n" " // subcircuit commons, recursive\n"; for (Args_List::const_iterator p = d.circuit().args_list().begin(); p != d.circuit().args_list().end(); ++p) { out << " COMMON_" << (**p).type() << "* " << (**p).name() << " = new COMMON_" << (**p).type() << ";\n"; for (Arg_List::const_iterator a = (**p).begin(); a != (**p).end(); ++a) { out << " " << (**p).name() << "->" << (**a).arg() << ";\n"; } out << " attach_common(" << (**p).name() << ", &_" << (**p).name() << ");\n\n"; } out << " assert(c == this);\n" "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ void make_cc_common(std::ofstream& out, const Device& d) { make_tag(); make_common_default_constructor(out, d); make_common_copy_constructor(out, d); make_common_destructor(out, d); make_common_operator_equal(out, d); make_common_set_param_by_index(out, d); make_common_param_is_printable(out, d); make_common_param_name(out, d); make_common_param_name_or_alias(out, d); make_common_param_value(out, d); make_common_expand(out, d); out << "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/mg_out_dev.cc000066400000000000000000000355751145401216200153220ustar00rootroot00000000000000/*$Id: mg_out_dev.cc,v 26.134 2009/11/29 03:44:57 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include "mg_out.h" /*--------------------------------------------------------------------------*/ static void make_dev_dispatcher(std::ofstream& out, const Device& d) { out << "namespace DEV_" << d.name() << "_DISPATCHER { \n" " static DEV_" << d.name() << " p0;\n" " static DISPATCHER::INSTALL\n" " d0(&device_dispatcher, \""; if (d.id_letter() != "") { out << d.id_letter() << '|'; }else{ } out << d.parse_name() << "\", &p0);\n" "}\n" "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_dev_eval(std::ofstream& out, const Eval& e, const String_Arg& dev_type, const String_Arg& model_type) { make_tag(); std::string class_name = "EVAL_" + dev_type.to_string() + '_' + e.name().to_string(); out << "static " << class_name << " Eval_" << e.name().to_string() << "(CC_STATIC);\n" "void " << class_name << "::tr_eval(ELEMENT* d)const\n" "{\n" " assert(d);\n" " DEV_" << dev_type << "* p = prechecked_cast(d->owner());\n" " assert(p);\n" " const COMMON_" << dev_type << "* c = prechecked_cast(p->common());\n" " assert(c);\n" " const SDP_" << model_type << "* s = prechecked_cast(c->sdp());\n" " assert(s);\n" " const MODEL_" << model_type << "* m = prechecked_cast(c->model());\n" " assert(m);\n" << e.code() << "}\n" "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_dev_evals(std::ofstream& out, const Device& d) { make_tag(); for (Eval_List::const_iterator e = d.eval_list().begin(); e != d.eval_list().end(); ++e) { make_dev_eval(out, **e, d.name(), d.model_type()); } } /*--------------------------------------------------------------------------*/ void make_dev_default_constructor(std::ofstream& out,const Device& d) { make_tag(); out << "DEV_" << d.name() << "::DEV_" << d.name() << "()\n" " :BASE_SUBCKT()"; out << ",\n // input parameters"; make_construct_parameter_list(out, d.device().raw()); out << ",\n // calculated parameters"; make_construct_parameter_list(out, d.device().calculated()); out << ",\n // netlist"; for (Element_List::const_iterator p = d.circuit().elements().begin(); p != d.circuit().elements().end(); ++p) { out << ",\n _" << (**p).name() << "(0)"; } out << "\n{\n" " _n = _nodes;\n" " attach_common(&Default_" << d.name() << ");\n" " ++_count;\n"; out << " // overrides\n"; for (Parameter_List::const_iterator p = d.device().override().begin(); p != d.device().override().end(); ++p) {untested(); if (!((**p).final_default().empty())) {untested(); out << " " << (**p).code_name() << " = NA;\n"; }else{untested(); } if (!((**p).default_val().empty())) {untested(); out << " " << (**p).code_name() << " = " << (**p).default_val() <<";\n"; }else{untested(); } } out << "}\n" "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ void make_dev_copy_constructor(std::ofstream& out, const Device& d) { make_tag(); out << "DEV_" << d.name() << "::DEV_" << d.name() << "(const DEV_" << d.name() << "& p)\n" " :BASE_SUBCKT(p)"; out << ",\n // input parameters"; make_copy_construct_parameter_list(out, d.device().raw()); out << ",\n // calculated parameters"; make_copy_construct_parameter_list(out, d.device().calculated()); out << ",\n // netlist"; for (Element_List::const_iterator p = d.circuit().elements().begin(); p != d.circuit().elements().end(); ++p) { out << ",\n _" << (**p).name() << "(0)"; } out << "\n{\n" " _n = _nodes;\n" " for (int ii = 0; ii < max_nodes() + int_nodes(); ++ii) {\n" " _n[ii] = p._n[ii];\n" " }\n" " ++_count;\n"; out << " // overrides\n"; for (Parameter_List::const_iterator p = d.device().override().begin(); p != d.device().override().end(); ++p) {untested(); out << ",\n " << (**p).code_name() << "(p." << (**p).code_name() << ")"; } out << "}\n" "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_set_parameters(std::ofstream& out, const Element& e) { make_tag(); out << " _" << e.name() << "->set_parameters(\"" << e.name() << "\", this, "; if (e.eval() != "") { out << "&Eval_" << e.eval(); }else if (e.args() != "") { out << "c->_" << e.args(); }else{ out << "NULL"; } out << ", " << ((e.value() != "") ? e.value() : "0."); if (e.state() != "") { out << ", " << e.num_nodes()/2+1 << ", &" << e.state(); }else{ out << ", 0, NULL"; } out << ", " << e.num_nodes() << ", nodes);\n"; } /*--------------------------------------------------------------------------*/ static void make_dev_expand_one_element(std::ofstream& out, const Element& e) { make_tag(); if (!(e.omit().empty())) { out << " if (" << e.omit() << ") {\n" " if (_" << e.name() << ") {\n" " subckt()->erase(_" << e.name() << ");\n" " _" << e.name() << " = NULL;\n" " }else{\n" " }\n" " }else{\n"; }else{ out << " {\n"; } out << " if (!_" << e.name() << ") {\n" " const CARD* p = device_dispatcher[\"" << e.dev_type() << "\"];\n" " assert(p);\n" " _" << e.name() << " = dynamic_cast(p->clone());\n" " assert(_" << e.name() << ");\n" " subckt()->push_front(_" << e.name() << ");\n" " }else{\n" " }\n"; if (!(e.reverse().empty())) { out << " if (" << e.reverse() << ") {\n"; out << " node_t nodes[] = {"; Port_List::const_iterator p = e.ports().begin(); if (p != e.ports().end()) { Port_List::const_iterator even = p; ++p; assert(p != e.ports().end()); out<< "_n[n_" << (**p).name() << "], _n[n_" << (**even).name() << "]"; bool even_node = true; while (++p != e.ports().end()) {untested(); if (even_node) {untested(); even_node = false; even = p; }else{untested(); even_node = true; out<< ", _n[n_"<< (**p).name()<< "], _n[n_"<<(**even).name()<< "]"; } } }else{untested(); } out << " };\n"; make_set_parameters(out, e); out << " }else{\n"; }else{ out << " {\n"; } out << " node_t nodes[] = {"; Port_List::const_iterator p = e.ports().begin(); if (p != e.ports().end()) { assert(*p); out << "_n[n_" << (**p).name() << "]"; while (++p != e.ports().end()) { out << ", _n[n_" << (**p).name() << "]"; } }else{untested(); } out << "};\n"; make_set_parameters(out, e); out << " }\n"; out << " }\n"; } /*--------------------------------------------------------------------------*/ static void make_dev_allocate_local_nodes(std::ofstream& out, const Port& p) { make_tag(); if (p.short_if().empty()) {untested(); out << " assert(!(_n[n_" << p.name() << "].n_()));\n" " _n[n_" << p.name() << "].new_model_node();\n"; }else{ out << " //assert(!(_n[n_" << p.name() << "].n_()));\n" " //BUG// this assert fails on a repeat elaboration after a change.\n" " //not sure of consequences when new_model_node called twice.\n" " if (!(_n[n_" << p.name() << "].n_())) {\n" " if (" << p.short_if() << ") {\n" " _n[n_" << p.name() << "] = _n[n_" << p.short_to() << "];\n" " }else{\n" " _n[n_" << p.name() << "].new_model_node(\".\" + long_label() + \"." << p.name() << "\", this);\n" " }\n" " }else{\n" " if (" << p.short_if() << ") {\n" " assert(_n[n_" << p.name() << "] == _n[n_" << p.short_to() << "]);\n" " }else{\n" " //_n[n_" << p.name() << "].new_model_node(\"" << p.name() << ".\" + long_label(), this);\n" " }\n" " }\n"; } } /*--------------------------------------------------------------------------*/ static void make_dev_expand(std::ofstream& out, const Device& d) { make_tag(); out << "void DEV_" << d.name() << "::expand()\n" "{\n" " BASE_SUBCKT::expand(); // calls common->expand, attached model\n" " assert(_n);\n" " assert(common());\n" " const COMMON_" << d.name() << "* c = static_cast(common());\n" " assert(c);\n" " assert(c->model());\n" " const MODEL_" << d.model_type() << "* m = prechecked_cast(c->model());\n" " assert(m);\n" " assert(c->sdp());\n" " const SDP_" << d.model_type() << "* s = prechecked_cast(c->sdp());\n" " assert(s);\n" " if (!subckt()) {\n" " new_subckt();\n" " }else{\n" " }\n" "\n" " if (_sim->is_first_expand()) {\n" " precalc_first();\n" " precalc_last();\n" " // local nodes\n"; for (Port_List::const_iterator p = d.circuit().local_nodes().begin(); p != d.circuit().local_nodes().end(); ++p) { make_dev_allocate_local_nodes(out, **p); } out << "\n" " // clone subckt elements\n"; for (Element_List::const_iterator e = d.circuit().elements().begin(); e != d.circuit().elements().end(); ++e) { make_dev_expand_one_element(out, **e); } out << " }else{\n" " //precalc();\n" " }\n" " //precalc();\n" " subckt()->expand();\n" " //subckt()->precalc();\n" " assert(!is_constant());\n"; if (d.circuit().sync()) { out << " subckt()->set_slave();\n"; }else{ } out << "}\n" "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static std::string fix_expression(const std::string& in) { std::string out; out[0] = '\0'; CS x(CS::_STRING, in); for (;;) { if (x.peek() == '@') { x.skip1('@'); std::string object(x.ctos("[,")); x.skip1('['); std::string attrib(x.ctos("]")); x.skip1(']'); if (object[0] == 'n') { out += " _n[" + object + "]"; if (attrib != "") { out += ".v0()"; }else{ } }else{ out += " CARD::probe(_" + object + ",\"" + attrib + "\")"; } }else if (x.more()) { out += ' ' + x.ctos("@"); }else{ break; } } return out; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ static void make_probe_parameter(std::ofstream& out, const Parameter& p) { make_tag(); out << "if (Umatch(x, \""; if (!(p.alt_name().empty())) {untested(); out << to_lower(p.alt_name()) << " \" || \""; } out << to_lower(p.user_name()) << " \")) {\n" " return " << p.code_name() << ";\n" " }else "; } /*--------------------------------------------------------------------------*/ void make_probe_parameter_list(std::ofstream& out,const Parameter_List& pl) { make_tag(); for (Parameter_List::const_iterator p = pl.begin(); p != pl.end(); ++p) { make_probe_parameter(out, **p); } } /*--------------------------------------------------------------------------*/ static void make_dev_probe(std::ofstream& out, const Device& d) { make_tag(); out << "double DEV_" << d.name() << "::tr_probe_num(const std::string& x)const\n" "{\n" " assert(_n);\n" " const COMMON_" << d.name() << "* c = prechecked_cast(common());\n" " assert(c);\n" " const MODEL_" << d.model_type() << "* m = prechecked_cast(c->model());\n" " assert(m);\n" " const SDP_" << d.model_type() << "* s = prechecked_cast(c->sdp());\n" " assert(s);\n" "\n" " "; for (Probe_List::const_iterator p = d.probes().begin(); p != d.probes().end(); ++p) { assert(*p); out << "if (Umatch(x, \"" << (**p).name() << " \")) {\n" " return " << fix_expression((**p).expression()) << ";\n" " }else "; } make_probe_parameter_list(out, d.device().calculated()); out << "{\n" " return BASE_SUBCKT::tr_probe_num(x);\n" " }\n" "}\n" "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_dev_aux(std::ofstream& out, const Device& d) { make_tag(); for (Function_List::const_iterator p = d.function_list().begin(); p != d.function_list().end(); ++p) { out << "void DEV_" << d.name() << "::" << (**p).name() << "\n" "{\n" << (**p).code() << "}\n" "/*--------------------------------------" "------------------------------------*/\n"; } } /*--------------------------------------------------------------------------*/ void make_cc_dev(std::ofstream& out, const Device& d) { make_tag(); make_dev_dispatcher(out, d); make_dev_evals(out, d); make_dev_default_constructor(out, d); make_dev_copy_constructor(out, d); make_dev_expand(out, d); make_dev_probe(out, d); make_dev_aux(out, d); out << "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/mg_out_dump.cc000066400000000000000000000052511145401216200154750ustar00rootroot00000000000000/*$Id: mg_out_dump.cc,v 26.81 2008/05/27 05:33:43 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include "md.h" #include "mg_out.h" /*--------------------------------------------------------------------------*/ static void make_header(std::ofstream& out, const File& in) { out << in.head(); } /*--------------------------------------------------------------------------*/ static void make_tail(std::ofstream& out) { out << "/*--------------------------------------" "------------------------------------*/\n" "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void make_dump_file(const File& in) { std::string dump_name = in.name(); { // chop suffix .model std::string::size_type loc = dump_name.rfind(".model"); if (loc == std::string::npos) { untested(); loc = dump_name.rfind(".vams"); }else{ } if (loc != std::string::npos) { dump_name.erase(loc); }else{ untested(); } } { // chop prefix path std::string::size_type loc = dump_name.find_last_of(ENDDIR); if (loc != std::string::npos) { dump_name.erase(0, loc+1); }else{ } } // open file std::ofstream out((dump_name+".dump").c_str()); if (!out) { untested(); os_error(dump_name); } make_header(out, in); out << "h_headers {" << in.h_headers() << "}\n" "cc_headers {" << in.cc_headers() << "}\n" << in.devices() << in.models() << "h_direct {" << in.h_direct() << "}\n" "cc_direct {" << in.cc_direct() << "}\n"; make_tail(out); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/mg_out_h.cc000066400000000000000000000420031145401216200147530ustar00rootroot00000000000000/*$Id: mg_out_h.cc,v 26.134 2009/11/29 03:44:57 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script 2006.11.01 #include "mg_out.h" /*--------------------------------------------------------------------------*/ static void make_header(std::ofstream& out, const File& in, const std::string& dump_name) { out << in.head() << "/* This file is automatically generated. DO NOT EDIT */\n" "#ifndef " << to_upper(dump_name) << "_H_INCLUDED\n" "#define " << to_upper(dump_name) << "_H_INCLUDED\n" << in.h_headers() << "#include \"u_sdp.h\"\n" "#include \"e_node.h\"\n" "#include \"e_subckt.h\"\n" "#include \"e_model.h\"\n" "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_sdp(std::ofstream& out, const Model& m) { out << "class SDP_" << m.name() << "\n :public SDP_" << m.inherit() << "{\n" "public:\n" " explicit SDP_" << m.name() << "(const COMMON_COMPONENT* c) : SDP_" << m.inherit() << "(c) {init(c);}\n" " void init(const COMMON_COMPONENT*);\n" "public:\n"; Parameter_List::const_iterator p = m.size_dependent().raw().begin(); for (;;) { if (p == m.size_dependent().raw().end()) { p = m.size_dependent().calculated().begin(); }else{ } if (p == m.size_dependent().calculated().end()) { break; }else{ } out << " " << (**p).type() << " " << (**p).code_name() << ";\t// " << (**p).comment() << '\n'; ++p; } out << "};\n" "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_tdp(std::ofstream& out, const Model& m) { out << "class DEV_" << m.dev_type() << ";\n"; out << "class TDP_" << m.name(); if (!m.hide_base()) { out << "\n :public TDP_" << m.inherit(); }else{ } out << "{\n" "public:\n" " explicit TDP_"<< m.name() <<"(const DEV_" << m.dev_type() << "*);\n" "public:\n"; for (Parameter_List::const_iterator p = m.temperature().calculated().begin(); p != m.temperature().calculated().end(); ++p) { out << " " << (**p).type() << " " << (**p).code_name() << ";\t// " << (**p).comment() << '\n'; } out << "};\n" "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_model(std::ofstream& out, const Model& m) { std::string class_name = "MODEL_" + m.name().to_string(); out << "class " << class_name << "\n" " :public MODEL_" << m.inherit() << "{\n" "protected:\n" " explicit " << class_name << "(const " << class_name << "& p);\n" "public:\n" " explicit " << class_name << "(const BASE_SUBCKT*);\n" " ~" << class_name << "() {--_count;}\n" "public: // override virtual\n" " std::string dev_type()const;\n" " void set_dev_type(const std::string& nt);\n" " CARD* clone()const {return new " << class_name << "(*this);}\n" " void precalc_first();\n" " void precalc_last();\n" " SDP_CARD* new_sdp(COMMON_COMPONENT* c)const;\n" " void set_param_by_index(int, std::string&, int);\n" " bool param_is_printable(int)const;\n" " std::string param_name(int)const;\n" " std::string param_name(int,int)const;\n" " std::string param_value(int)const;\n" " int param_count()const {return (" << 1 + m.independent().override().size() + 4 * m.size_dependent().raw().size() + m.independent().raw().size(); if (!m.hide_base()) { out << " + MODEL_" << m.inherit() << "::param_count());}\n"; }else{ out << ");}\n"; } out << " bool is_valid(const COMPONENT*)const;\n" " void tr_eval(COMPONENT*)const;\n" "public: // not virtual\n" " static int count() {return _count;}\n" "private: // strictly internal\n"; out << " static int _count;\n" "public: // input parameters\n"; for (Parameter_List::const_iterator p = m.size_dependent().raw().begin(); p != m.size_dependent().raw().end(); ++p) { out << " " << "SDP" << " " << (**p).code_name() << ";\t// " << (**p).comment() << '\n'; } for (Parameter_List::const_iterator p = m.independent().raw().begin(); p != m.independent().raw().end(); ++p) { out << " PARAMETER<" << (**p).type() << "> " << (**p).code_name() << ";\t// " << (**p).comment() << '\n'; } out << "public: // calculated parameters\n"; for (Parameter_List::const_iterator p = m.independent().calculated().begin(); p != m.independent().calculated().end(); ++p) { out << " " << (**p).type() << " " << (**p).code_name() << ";\t// " << (**p).comment() << '\n'; } out << "};\n" "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_common(std::ofstream& out, const Device& d) { std::string class_name = "COMMON_" + d.name().to_string(); out << "class " << class_name << "\n" " :public COMMON_COMPONENT{\n" "public:\n" " explicit " << class_name << "(const " << class_name << "& p);\n" " explicit " << class_name << "(int c=0);\n" " ~" << class_name << "();\n" " bool operator==(const COMMON_COMPONENT&)const;\n" " COMMON_COMPONENT* clone()const {return new "< " << (**p).code_name() << ";\t// " << (**p).comment() << '\n'; } out << "public: // calculated parameters\n" " SDP_CARD* _sdp;\n"; for (Parameter_List::const_iterator p = d.common().calculated().begin(); p != d.common().calculated().end(); ++p) { out << " " << (**p).type() << " " << (**p).code_name() << ";\t// " << (**p).comment() << '\n'; } out << "public: // attached commons\n"; for (Args_List::const_iterator p = d.circuit().args_list().begin(); p != d.circuit().args_list().end(); ++p) { out << " COMMON_COMPONENT* _" << (**p).name() << ";\n"; } out << "};\n" "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_device(std::ofstream& out, const Device& d) { std::string class_name = "DEV_" + d.name().to_string(); out << "class " << class_name << " : public BASE_SUBCKT {\n" "private:\n" " explicit " << class_name << "(const " << class_name << "& p);\n" "public:\n" " explicit " << class_name << "();\n" " ~" << class_name << "() {--_count;}\n" "private: // override virtual\n" " char id_letter()const {untested();return '" << d.id_letter() << "';}\n" " bool print_type_in_spice()const {return true;}\n" " std::string value_name()const {return \"area\";}\n" " //std::string dev_type()const; //BASE_SUBCKT\n" " int max_nodes()const {return " << d.max_nodes() << ";}\n" " int min_nodes()const {return " << d.min_nodes() << ";}\n"; if (d.max_nodes() != d.min_nodes()) { out << " //int matrix_nodes()const; //BASE_SUBCKT\n" " //int net_nodes()const; //BASE_SUBCKT\n"; }else{ out << " //int matrix_nodes()const; //BASE_SUBCKT\n" " int net_nodes()const {return " << d.max_nodes() << ";}\n"; } out << " int int_nodes()const {return " << d.circuit().local_nodes().size() << ";}\n" " CARD* clone()const {return new " << class_name << "(*this);}\n" " void precalc_first() {COMPONENT::precalc_first(); if(subckt()) subckt()->precalc_first();}\n" " void expand();\n" " void precalc_last() {COMPONENT::precalc_last(); assert(subckt()); subckt()->precalc_last();}\n" " //void map_nodes(); //BASE_SUBCKT\n" " //void tr_begin(); //BASE_SUBCKT\n" " //void tr_restore(); //BASE_SUBCKT\n"; if (d.tr_eval().is_empty()) { out << " //void dc_advance(); //BASE_SUBCKT\n" " //void tr_advance(); //BASE_SUBCKT\n" " //void tr_regress(); //BASE_SUBCKT\n" " //bool tr_needs_eval()const;//BASE_SUBCKT\n" " //void tr_queue_eval(); //BASE_SUBCKT\n" " //bool do_tr(); //BASE_SUBCKT\n"; }else{ out << " void dc_advance() {set_not_converged(); BASE_SUBCKT::dc_advance();}\n" " void tr_advance() {set_not_converged(); BASE_SUBCKT::tr_advance();}\n" " void tr_regress() {set_not_converged(); BASE_SUBCKT::tr_regress();}\n" " bool tr_needs_eval()const;\n" " void tr_queue_eval() {if(tr_needs_eval()){q_eval();}}\n" " bool do_tr();\n"; } out << " //void tr_load(); //BASE_SUBCKT\n" " //double tr_review(); //BASE_SUBCKT\n" " //void tr_accept(); //BASE_SUBCKT\n" " //void tr_unload(); //BASE_SUBCKT\n" " double tr_probe_num(const std::string&)const;\n" " //void ac_begin(); //BASE_SUBCKT\n" " //void do_ac(); //BASE_SUBCKT\n" " //void ac_load(); //BASE_SUBCKT\n" " //XPROBE ac_probe_ext(CS&)const;//CKT_BASE/nothing\n" "public:\n" " static int count() {return _count;}\n" "public: // may be used by models\n"; for (Function_List::const_iterator p = d.function_list().begin(); p != d.function_list().end(); ++p) { out << " void " << (**p).name() << ";\n"; } out << "private: // not available even to models\n" " static int _count;\n"; out << "public: // input parameters\n"; for (Parameter_List::const_iterator p = d.device().raw().begin(); p != d.device().raw().end(); ++p) {untested(); untested(); out << " PARAMETER<" << (**p).type() << "> " << (**p).code_name() << ";\t// " << (**p).comment() << '\n'; } out << "public: // calculated parameters\n"; for (Parameter_List::const_iterator p = d.device().calculated().begin(); p != d.device().calculated().end(); ++p) { out << " " << (**p).type() << " " << (**p).code_name() << ";\t// " << (**p).comment() << '\n'; } out << "public: // netlist\n"; for (Element_List::const_iterator p = d.circuit().elements().begin(); p != d.circuit().elements().end(); ++p) { out << " COMPONENT* _" << (**p).name() << ";\n"; } out << "private: // node list\n" " enum {"; for (Port_List::const_iterator p = d.circuit().req_nodes().begin(); p != d.circuit().req_nodes().end(); ++p) { if (p != d.circuit().req_nodes().begin()) { out << ", "; }else{ } out << "n_" << (**p).name(); } for (Port_List::const_iterator p = d.circuit().opt_nodes().begin(); p != d.circuit().opt_nodes().end(); ++p) { out << ", "; out << "n_" << (**p).name(); } for (Port_List::const_iterator p = d.circuit().local_nodes().begin(); p != d.circuit().local_nodes().end(); ++p) { out << ", n_" << (**p).name(); } size_t total_nodes = d.circuit().req_nodes().size() + d.circuit().opt_nodes().size() + d.circuit().local_nodes().size(); out << "};\n" " node_t _nodes[" << total_nodes << "];\n" " std::string port_name(int i)const {\n" " assert(i >= 0);\n" " assert(i < " << d.circuit().req_nodes().size() + d.circuit().opt_nodes().size() << ");\n" " static std::string names[] = {"; for (Port_List::const_iterator p = d.circuit().req_nodes().begin(); p != d.circuit().req_nodes().end(); ++p) { out << '"' << (**p).name() << "\", "; } for (Port_List::const_iterator p = d.circuit().opt_nodes().begin(); p != d.circuit().opt_nodes().end(); ++p) { out << '"' << (**p).name() << "\", "; } out << "\"\"};\n" " return names[i];\n" " }\n" "};\n" "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_eval(std::ofstream& out, const Eval& e, const String_Arg& dev_name) { std::string class_name = "EVAL_" + dev_name.to_string() + '_' + e.name().to_string(); out << "class " << class_name << " : public COMMON_COMPONENT {\n" "private:\n" " explicit "<< class_name << "(const "<< class_name << "& p)\n" " :COMMON_COMPONENT(p) {}\n" "public:\n" " explicit "<< class_name << "(int c=0) :COMMON_COMPONENT(c) {}\n" " bool operator==(const COMMON_COMPONENT& x)const " "{return COMMON_COMPONENT::operator==(x);}\n" " COMMON_COMPONENT* clone()const {return new "< * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script 2006.11.01 #include "mg_out.h" /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void make_final_adjust_value(std::ofstream& out, const Parameter& p) { if (!(p.calculate().empty())) { out << " " << p.code_name() << " = " << p.calculate() << ";\n"; }else{ } if (!(p.final_default().empty())) { out << " if (" << p.code_name() << " == NA) {\n" " " << p.code_name() << " = " << p.final_default() << ";\n" " }else{\n" " }\n"; //out << " e_val(&(" << p.code_name() << "), " << p.final_default() // << ", par_scope);\n"; #if 0 }else if (!(p.default_val().empty())) { out << " if (" << p.code_name() << " == NA) {\n" " " << p.code_name() << " = " << p.default_val() << ";\n" " }else{\n" " }\n"; //out << " e_val(&(" << p.code_name() << "), " << p.default_val() // << ", par_scope);\n"; #endif }else{ } if (!(p.quiet_min().empty())) { out << " //" << p.code_name() << " = std::max(" << p.code_name() << ", " << p.quiet_min() << ");\n"; }else{ } if (!(p.quiet_max().empty())) { out << " //" << p.code_name() << " = std::min(" << p.code_name() << ", " << p.quiet_max() << ");\n"; }else{ } } /*--------------------------------------------------------------------------*/ void make_final_adjust_value_list(std::ofstream& out, const Parameter_List& pl) { for (Parameter_List::const_iterator p = pl.begin(); p != pl.end(); ++p) { make_final_adjust_value(out, **p); } } /*--------------------------------------------------------------------------*/ void make_final_adjust_eval_parameter(std::ofstream& out, const Parameter& p) { if (!(p.calculate().empty())) {untested(); out << " this->" << p.code_name() << " = " << p.calculate() << ";\n"; }else{ out << " e_val(&(this->" << p.code_name() << "), "; if (!(p.default_val().empty())) { out << p.default_val(); }else{ out << "NA"; } out << ", par_scope);\n"; } } /*--------------------------------------------------------------------------*/ void make_final_adjust_eval_parameter_list(std::ofstream& out, const Parameter_List& pl) { for (Parameter_List::const_iterator p = pl.begin(); p != pl.end(); ++p) { make_final_adjust_eval_parameter(out, **p); } } /*--------------------------------------------------------------------------*/ void make_final_adjust_parameter(std::ofstream& out, const Parameter& p) { if (!(p.calculate().empty())) { out << " this->" << p.code_name() << " = " << p.calculate() << ";\n"; }else{ out << " e_val(&(this->" << p.code_name() << "), "; if (!(p.final_default().empty())) { out << p.final_default(); }else if (!(p.default_val().empty())) { out << p.default_val(); }else{ out << "NA"; } out << ", par_scope);\n"; } if (!(p.quiet_min().empty())) { out << " //this->" << p.code_name() << " = std::max(" << p.code_name() << ", " << p.quiet_min() << ");\n"; }else{ } if (!(p.quiet_max().empty())) { out << " //this->" << p.code_name() << " = std::min(" << p.code_name() << ", " << p.quiet_max() << ");\n"; }else{ } } /*--------------------------------------------------------------------------*/ void make_final_adjust_parameter_list(std::ofstream& out, const Parameter_List& pl) { for (Parameter_List::const_iterator p = pl.begin(); p != pl.end(); ++p) { make_final_adjust_parameter(out, **p); } } /*--------------------------------------------------------------------------*/ void make_final_adjust(std::ofstream& out, const Parameter_Block& b) { //out << " // final adjust: eval\n"; //make_final_adjust_eval_parameter_list(out, b.raw()); out << " // final adjust: code_pre\n"; out << b.code_pre(); out << " // final adjust: override\n"; make_final_adjust_value_list(out, b.override()); out << " // final adjust: raw\n"; make_final_adjust_parameter_list(out, b.raw()); out << " // final adjust: mid\n"; out << b.code_mid(); out << " // final adjust: calculated\n"; make_final_adjust_value_list(out, b.calculated()); out << " // final adjust: post\n"; out << b.code_post(); out << " // final adjust: done\n"; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ static void make_construct_parameter(std::ofstream& out, const Parameter& p) { if (!(p.default_val().empty())) { out << ",\n " << p.code_name() << "(" << p.default_val() << ")"; }else{ out << ",\n " << p.code_name() << "(NA)"; } } /*--------------------------------------------------------------------------*/ void make_construct_parameter_list(std::ofstream& out,const Parameter_List& pl) { for (Parameter_List::const_iterator p = pl.begin(); p != pl.end(); ++p) { make_construct_parameter(out, **p); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ static void make_get_one_param(std::ofstream& out, const Parameter& p, const std::string& name) { if (!(name.empty())) { out << " || get(cmd, \"" << name << "\", &" << p.code_name(); if (!(p.offset().empty())) {untested(); incomplete(); out << ", m_OFFSET, " << p.offset(); }else if (p.positive()) { //incomplete(); //out << ", mPOSITIVE"; }else if (p.octal()) {untested(); incomplete(); out << ", m_OCTAL"; }else if (!(p.scale().empty())) {untested(); incomplete(); out << ", m_SCALE, " << p.scale(); }else{ } out << ")\n"; }else{ } } /*--------------------------------------------------------------------------*/ void make_get_param_list(std::ofstream& out, const Parameter_List& pl) { for (Parameter_List::const_iterator p = pl.begin(); p != pl.end(); ++p) { make_get_one_param(out, **p, (**p).user_name()); make_get_one_param(out, **p, (**p).alt_name()); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ static void make_print_one_param(std::ofstream& out, const Parameter& p) { if (!(p.user_name().empty())) { out << " print_pair(o, lang, \"" << to_lower(p.user_name()) << "\", " << p.code_name(); if (!(p.offset().empty())) {untested(); out << "-(" << p.offset() << ")"; }else{ } if (!(p.scale().empty())) {untested(); out << "/(" << p.scale() << ")"; }else{ } if (!(p.print_test().empty())) { out << ", " << p.print_test() << ""; }else if (p.default_val() == "NA") { out << ", " << p.code_name() << " != NA"; }else{ } out << ");\n"; }else{ } } /*--------------------------------------------------------------------------*/ void make_print_param_list(std::ofstream& out, const Parameter_List& pl) { for (Parameter_List::const_iterator p = pl.begin(); p != pl.end(); ++p) { make_print_one_param(out, **p); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ static void make_print_one_calc_param(std::ofstream& out, const Parameter& p) { if (!(p.user_name().empty()) && !(p.calc_print_test().empty())) { out << " if (" << p.calc_print_test() << ")\n " " o << \"* " << to_lower(p.user_name()) << "=\" << " << p.code_name(); if (!(p.offset().empty())) {untested(); out << "-(" << p.offset() << ")"; }else{ } if (!(p.scale().empty())) {untested(); out << "/(" << p.scale() << ")"; }else{ } out << ";\n"; }else{ } } /*--------------------------------------------------------------------------*/ void make_print_calc_param_list(std::ofstream& out, const Parameter_List& pl) { for (Parameter_List::const_iterator p = pl.begin(); p != pl.end(); ++p) { make_print_one_calc_param(out, **p); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ static void make_copy_construct_parameter(std::ofstream&out,const Parameter&p) { out << ",\n " << p.code_name() << "(p." << p.code_name() << ")"; } /*--------------------------------------------------------------------------*/ void make_copy_construct_parameter_list(std::ofstream& out, const Parameter_List& pl) { for (Parameter_List::const_iterator p = pl.begin(); p != pl.end(); ++p) { make_copy_construct_parameter(out, **p); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/mg_out_model.cc000066400000000000000000000654301145401216200156350ustar00rootroot00000000000000/*$Id: mg_out_model.cc,v 26.128 2009/11/10 04:21:03 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script 2006.11.01 #include "mg_out.h" /*--------------------------------------------------------------------------*/ static void make_model_dispatcher(std::ofstream& out, const Model& m) { if (m.level() != "") { out << "const int LEVEL(" << m.level() <<");\n" "/*--------------------------------------------------------------------------*/\n"; }else{ } if (!m.public_key_list().is_empty()) { out << "namespace MODEL_" << m.name() << "_DISPATCHER { \n" " static DEV_" << m.dev_type() << " p1d;\n" " static MODEL_" << m.name() << " p1(&p1d);\n" " static DISPATCHER::INSTALL\n" " d1(&model_dispatcher, \""; for (Key_List::const_iterator k = m.public_key_list().begin(); k != m.public_key_list().end(); ++k) { if (k != m.public_key_list().begin()) { out << '|'; }else{ } out << (**k).name(); } out << "\", &p1);\n" "}\n" "/*--------------------------------------------------------------------------*/\n"; }else{ } } /*--------------------------------------------------------------------------*/ static void make_sdp_constructor(std::ofstream& out, const Model& m) { #if 0 out << "SDP_" << m.name() << "::SDP_" << m.name() << "(const COMMON_COMPONENT* cc)\n" " :SDP_" << m.inherit() << "(cc)\n" "{\n"; #else out << "void SDP_" << m.name() << "::init(const COMMON_COMPONENT* cc)\n" "{\n" " assert(cc);\n" " SDP_" << m.inherit() << "::init(cc);\n"; #endif if (!m.size_dependent().is_empty()) { out << " const COMMON_" << m.dev_type() << "* c = prechecked_cast(cc);\n" " assert(c);\n" " const MODEL_" << m.name() << "* m = prechecked_cast(c->model());\n" " assert(m);\n" " const CARD_LIST* par_scope = m->scope();\n" " assert(par_scope);\n"; out << m.size_dependent().code_pre(); out << " // adjust: override\n"; make_final_adjust_parameter_list(out, m.size_dependent().override()); out << " // adjust: raw\n"; for (Parameter_List::const_iterator p = m.size_dependent().raw().begin(); p != m.size_dependent().raw().end(); ++p) { if (!((**p).final_default().empty())) { out << " " << (**p).code_name() << " = m->" << (**p).code_name() << "(L, W, " << (**p).final_default() << ", par_scope);\n"; }else if (!((**p).default_val().empty())) { out << " " << (**p).code_name() << " = m->" << (**p).code_name() << "(L, W, " << (**p).default_val() << ", par_scope);\n"; }else{untested(); out << " " << (**p).code_name() << " = m->" << (**p).code_name() << "(L, W, 0., par_scope);\n"; } make_final_adjust_value(out, **p); } out << " // adjust: calculated\n"; make_final_adjust_value_list(out, m.size_dependent().calculated()); out << " // code_post\n" << m.size_dependent().code_post(); }else{ } out << "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_tdp_constructor(std::ofstream& out, const Model& m) { out << "TDP_" << m.name() << "::TDP_" << m.name() << "(const DEV_" << m.dev_type() << '*'; if (!m.hide_base() || !m.temperature().is_empty()) { out << " d"; }else{ } out << ")\n"; if (!m.hide_base()) { out << " :TDP_" << m.inherit() << "(d)\n"; }else{ } out << "{\n"; if (!m.temperature().is_empty()) { out << " assert(d);\n" " const COMMON_" << m.dev_type() << "* c = prechecked_cast(d->common());\n" " assert(c);\n" " const SDP_" << m.name() << "* s = prechecked_cast(c->sdp());\n" " assert(s);\n" " const MODEL_" << m.name() << "* m = prechecked_cast(c->model());\n" " assert(m);\n" " const CARD_LIST* par_scope = d->scope();\n" " assert(par_scope);\n"; make_final_adjust_eval_parameter_list(out, m.temperature().raw()); make_final_adjust(out, m.temperature()); }else{ } out << "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_model_default_constructor(std::ofstream& out, const Model& m) { out << "MODEL_" << m.name() << "::MODEL_" << m.name() << "(const BASE_SUBCKT* p)\n" " :MODEL_" << m.inherit() << "(p)"; make_construct_parameter_list(out, m.size_dependent().raw()); make_construct_parameter_list(out, m.independent().raw()); make_construct_parameter_list(out, m.independent().calculated()); out << "\n{\n" " if (ENV::run_mode != rPRE_MAIN) {\n" " ++_count;\n" " }else{\n" " }\n"; for (Parameter_List::const_iterator p = m.independent().override().begin(); p != m.independent().override().end(); ++p) { if (!((**p).final_default().empty())) { //out << " " << (**p).code_name() << " = NA;\n"; out << " set_default(&" << (**p).code_name() << ", NA);\n"; }else{ } if (!((**p).default_val().empty())) { //out << " " << (**p).code_name() << " = " // << (**p).default_val() << ";\n"; out << " set_default(&" << (**p).code_name() << ", " << (**p).default_val() << ");\n"; }else{ } } out << "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_model_copy_constructor(std::ofstream& out, const Model& m) { out << "MODEL_" << m.name() << "::MODEL_" << m.name() << "(const MODEL_" << m.name() << "& p)\n" " :MODEL_" << m.inherit() << "(p)"; make_copy_construct_parameter_list(out, m.size_dependent().raw()); make_copy_construct_parameter_list(out, m.independent().raw()); make_copy_construct_parameter_list(out, m.independent().calculated()); out << "\n{\n" " if (ENV::run_mode != rPRE_MAIN) {\n" " ++_count;\n" " }else{untested();//194\n" " }\n"; #if 0 for (Parameter_List::const_iterator p = m.independent().override().begin(); p != m.independent().override().end(); ++p) {untested(); out << " itested();\n"; //out << ",\n " << (**p).code_name() << "(p." << (**p).code_name() << ")"; } #endif out << "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_model_dev_type(std::ofstream& out, const Model& m) { out << "std::string MODEL_" << m.name() << "::dev_type()const\n"; if (!m.public_key_list().is_empty() || !m.private_key_list().is_empty()) { out << "{\n" " "; Key_List::const_iterator k = (m.public_key_list().is_empty()) ? m.private_key_list().begin() : m.public_key_list().begin(); for (;;) { out << "if (" << (**k).var() << " == " << (**k).value() << ") {\n" " return \"" << (**k).name() << "\";\n"; ++k; if (k == m.public_key_list().end()) { k = m.private_key_list().begin(); }else{ } if (k == m.private_key_list().end()) { break; }else{ } out << " }else "; } out << " }else{untested();//235\n" " return MODEL_" << m.inherit() << "::dev_type();\n" " }\n"; }else{ out << "{untested();//240\n" " return MODEL_" << m.inherit() << "::dev_type();\n"; } out << "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_model_set_dev_type(std::ofstream& out, const Model& m) { out << "void MODEL_" << m.name() << "::set_dev_type(const std::string& new_type)\n" "{\n" " "; if (!m.public_key_list().is_empty() || !m.private_key_list().is_empty()) { Key_List::const_iterator k = (m.public_key_list().is_empty()) ? m.private_key_list().begin() : m.public_key_list().begin(); for (;;) { out << "if (Umatch(new_type, \"" << (**k).name() << " \")) {\n" " " << (**k).var() << " = " << (**k).value() << ";\n"; ++k; if (k == m.public_key_list().end()) { k = m.private_key_list().begin(); }else{ } if (k == m.private_key_list().end()) { break; }else{ } out << " }else "; } out << " }else{\n"; }else{ out << "{\n"; } if (!m.hide_base()) { out << " MODEL_" << m.inherit() << "::set_dev_type(new_type);\n"; }else{ out << " MODEL_CARD::set_dev_type(new_type);\n"; } out << " }\n"; out << "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_model_precalc(std::ofstream& out, const Model& m) { out << "void MODEL_" << m.name() << "::precalc_first()\n" "{\n" " const CARD_LIST* par_scope = scope();\n" " assert(par_scope);\n"; if (!m.hide_base()) { out << " MODEL_" << m.inherit() << "::precalc_first();\n"; }else{ out << " MODEL_CARD::precalc_first();\n"; } make_final_adjust_eval_parameter_list(out, m.independent().raw()); make_final_adjust(out, m.independent()); out << "}\n" "/*--------------------------------------------------------------------------*/\n"; out << "void MODEL_" << m.name() << "::precalc_last()\n" "{\n"; if (!m.hide_base()) { out << " MODEL_" << m.inherit() << "::precalc_last();\n"; }else{ out << " MODEL_CARD::precalc_last();\n"; } out << "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_model_new_sdp(std::ofstream& out, const Model& m) { out << "SDP_CARD* MODEL_" << m.name() << "::new_sdp(COMMON_COMPONENT* c)const\n" "{\n" " assert(c);\n" " if (COMMON_" << m.dev_type() << "* cc = dynamic_cast(c)) {\n" " if (cc->_sdp) {\n" " cc->_sdp->init(cc);\n" " return cc->_sdp;\n" " }else{\n" " delete cc->_sdp;\n" " return new SDP_" << m.name() << "(c);\n" " }\n" " }else{\n" " return MODEL_" << m.inherit() << "::new_sdp(c);\n" " }\n" "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_model_set_param_by_index(std::ofstream& out, const Model& m) { out << "void MODEL_" << m.name() << "::set_param_by_index(int i, std::string& value, int offset)\n" "{\n" " switch (MODEL_" << m.name() << "::param_count() - 1 - i) {\n"; size_t i = 0; if (m.level() != "") { out << " case " << i++ << ": level = value; break; //" << m.level() << "\n"; }else{ out << " case " << i++ << ": untested(); break;\n"; } for (Parameter_List::const_iterator p = m.independent().override().begin(); p != m.independent().override().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": " << (**p).code_name() << " = value; break;\n"; }else{ out << " case " << i++ << ": unreachable(); break;\n"; } } assert(i == 1 + m.independent().override().size()); for (Parameter_List::const_iterator p = m.size_dependent().raw().begin(); p != m.size_dependent().raw().end(); ++p) { out << " case " << i++ << ": " << (**p).code_name() << ".set_nom(value); break;\n"; out << " case " << i++ << ": " << (**p).code_name() << ".set_w(value); break;\n"; out << " case " << i++ << ": " << (**p).code_name() << ".set_l(value); break;\n"; out << " case " << i++ << ": " << (**p).code_name() << ".set_p(value); break;\n"; } assert(i == 1 + m.independent().override().size() + 4 * m.size_dependent().raw().size()); for (Parameter_List::const_iterator p = m.independent().raw().begin(); p != m.independent().raw().end(); ++p) { out << " case " << i++ << ": " << (**p).code_name() << " = value; break;\n"; } assert(i == 1 + m.independent().override().size() + 4 * m.size_dependent().raw().size() + m.independent().raw().size()); if (!m.hide_base()) { out << " default: MODEL_" << m.inherit() << "::set_param_by_index(i, value, offset); break;\n"; }else{ out << " default: throw Exception_Too_Many(i, " << i-1 << ", offset); break;\n"; } out << " }\n" "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ void make_model_param_is_printable(std::ofstream& out, const Model& m) { make_tag(); out << "bool MODEL_" << m.name() << "::param_is_printable(int i)const\n" "{\n" " switch (MODEL_" << m.name() << "::param_count() - 1 - i) {\n"; size_t i = 0; if (m.level() != "") { out << " case " << i++ << ": return (true);\n"; }else{ out << " case " << i++ << ": return (false);\n"; } for (Parameter_List::const_iterator p = m.independent().override().begin(); p != m.independent().override().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": return ("; if (!((**p).print_test().empty())) { out << (**p).print_test() << ");\n"; //}else if ((**p).default_val() == "NA" && (**p).final_default().empty()) {untested(); //out << (**p).code_name() << ".has_hard_value());\n"; //" != NA);\n"; }else if ((**p).default_val() == "NA") { out << (**p).code_name() << ".has_hard_value());\n"; }else{ out << "true);\n"; } }else{ out << " case " << i++ << ": return (false);\n"; } } assert(i == 1 + m.independent().override().size()); for (Parameter_List::const_iterator p = m.size_dependent().raw().begin(); p != m.size_dependent().raw().end(); ++p) { out << " case " << i++ << ": return ("; if (!((**p).print_test().empty())) { out << (**p).print_test() << ");\n"; }else if ((**p).default_val() == "NA") { out << (**p).code_name() << ".has_value());\n"; }else{ out << "true);\n"; } out << " case " << i++ << ": return (" << (**p).code_name() << ".w_has_value());\n"; out << " case " << i++ << ": return (" << (**p).code_name() << ".l_has_value());\n"; out << " case " << i++ << ": return (" << (**p).code_name() << ".p_has_value());\n"; } assert(i == 1 + m.independent().override().size() + 4 * m.size_dependent().raw().size()); for (Parameter_List::const_iterator p = m.independent().raw().begin(); p != m.independent().raw().end(); ++p) { out << " case " << i++ << ": return ("; if (!((**p).print_test().empty())) { out << (**p).print_test() << ");\n"; //}else if ((**p).default_val() == "NA" && (**p).final_default().empty()) { //out << (**p).code_name() << ".has_hard_value());\n"; //" != NA);\n"; }else if ((**p).default_val() == "NA") { out << (**p).code_name() << ".has_hard_value());\n"; }else{ out << "true);\n"; } } assert(i == 1 + m.independent().override().size() + 4 * m.size_dependent().raw().size() + m.independent().raw().size()); if (!m.hide_base()) { out << " default: return MODEL_" << m.inherit() << "::param_is_printable(i);\n"; }else{ out << " default: return false;\n"; } out << " }\n" "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ void make_model_param_name(std::ofstream& out, const Model& m) { make_tag(); out << "std::string MODEL_" << m.name() << "::param_name(int i)const\n" "{\n" " switch (MODEL_" << m.name() << "::param_count() - 1 - i) {\n"; size_t i = 0; if (m.level() != "") { out << " case " << i++ << ": return \"level\";\n"; }else{ out << " case " << i++ << ": return \"=====\";\n"; } for (Parameter_List::const_iterator p = m.independent().override().begin(); p != m.independent().override().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": return \"" << to_lower((**p).user_name()) << "\";\n"; }else{ out << " case " << i++ << ": return \"=====\";\n"; } } assert(i == 1 + m.independent().override().size()); for (Parameter_List::const_iterator p = m.size_dependent().raw().begin(); p != m.size_dependent().raw().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": return \"" << to_lower((**p).user_name()) << "\";\n"; out << " case " << i++ << ": return \"w" << to_lower((**p).user_name()) << "\";\n"; out << " case " << i++ << ": return \"l" << to_lower((**p).user_name()) << "\";\n"; out << " case " << i++ << ": return \"p" << to_lower((**p).user_name()) << "\";\n"; }else{unreachable(); out << " case " << i++ << ": return \"=====\";\n"; } } assert(i == 1 + m.independent().override().size() + 4 * m.size_dependent().raw().size()); for (Parameter_List::const_iterator p = m.independent().raw().begin(); p != m.independent().raw().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": return \"" << to_lower((**p).user_name()) << "\";\n"; }else{unreachable(); out << " case " << i++ << ": return \"=====\";\n"; } } assert(i == 1 + m.independent().override().size() + 4 * m.size_dependent().raw().size() + m.independent().raw().size()); if (!m.hide_base()) { out << " default: return MODEL_" << m.inherit() << "::param_name(i);\n"; }else{ out << " default: return \"\";\n"; } out << " }\n" "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ void make_model_param_name_or_alias(std::ofstream& out, const Model& m) { make_tag(); out << "std::string MODEL_" << m.name() << "::param_name(int i, int j)const\n" "{\n" " if (j == 0) {\n" " return param_name(i);\n" " }else if (j == 1) {\n" " switch (MODEL_" << m.name() << "::param_count() - 1 - i) {\n"; size_t i = 0; if (m.level() != "") { out << " case " << i++ << ": return \"\";\n"; }else{ out << " case " << i++ << ": return \"\";\n"; } for (Parameter_List::const_iterator p = m.independent().override().begin(); p != m.independent().override().end(); ++p) { out << " case " << i++ << ": return \"" << to_lower((**p).alt_name()) << "\";\n"; } assert(i == 1 + m.independent().override().size()); for (Parameter_List::const_iterator p = m.size_dependent().raw().begin(); p != m.size_dependent().raw().end(); ++p) { if (!((**p).user_name().empty())) { if (!((**p).alt_name().empty())) { out << " case " << i++ << ": return \"" << to_lower((**p).alt_name()) << "\";\n"; out << " case " << i++ << ": return \"w" << to_lower((**p).alt_name()) << "\";\n"; out << " case " << i++ << ": return \"l" << to_lower((**p).alt_name()) << "\";\n"; out << " case " << i++ << ": return \"p" << to_lower((**p).alt_name()) << "\";\n"; }else{ out << " case " << i++ << ": return \"\";\n"; out << " case " << i++ << ": return \"\";\n"; out << " case " << i++ << ": return \"\";\n"; out << " case " << i++ << ": return \"\";\n"; } }else{unreachable(); out << " case " << i++ << ": return \"\";\n"; out << " case " << i++ << ": return \"\";\n"; out << " case " << i++ << ": return \"\";\n"; out << " case " << i++ << ": return \"\";\n"; } } assert(i == 1 + m.independent().override().size() + 4 * m.size_dependent().raw().size()); for (Parameter_List::const_iterator p = m.independent().raw().begin(); p != m.independent().raw().end(); ++p) { out << " case " << i++ << ": return \"" << to_lower((**p).alt_name()) << "\";\n"; } assert(i == 1 + m.independent().override().size() + 4 * m.size_dependent().raw().size() + m.independent().raw().size()); if (!m.hide_base()) { out << " default: return MODEL_" << m.inherit() << "::param_name(i, j);\n"; }else{ out << " default: return \"\";\n"; } out << " }\n"; if (!m.hide_base()) { out << " }else if (i < " << i << ") {\n" " return \"\";\n" " }else{\n" " return MODEL_" << m.inherit() << "::param_name(i, j);\n"; }else{ out << " }else{\n" " return \"\";\n"; } out << " }\n" "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ void make_model_param_value(std::ofstream& out, const Model& m) { make_tag(); out << "std::string MODEL_" << m.name() << "::param_value(int i)const\n" "{\n" " switch (MODEL_" << m.name() << "::param_count() - 1 - i) {\n"; size_t i = 0; if (m.level() != "") { out << " case " << i++ << ": return \"" << m.level() << "\";\n"; }else{ out << " case " << i++ << ": unreachable(); return \"\";\n"; } for (Parameter_List::const_iterator p = m.independent().override().begin(); p != m.independent().override().end(); ++p) { if (!((**p).user_name().empty())) { out << " case " << i++ << ": return " << (**p).code_name() << ".string();\n"; }else{ out << " case " << i++ << ": unreachable(); return \"\";\n"; } } assert(i == 1 + m.independent().override().size()); for (Parameter_List::const_iterator p = m.size_dependent().raw().begin(); p != m.size_dependent().raw().end(); ++p) { out << " case " << i++ << ": return " << (**p).code_name() << ".string();\n"; out << " case " << i++ << ": return " << (**p).code_name() << ".w_string();\n"; out << " case " << i++ << ": return " << (**p).code_name() << ".l_string();\n"; out << " case " << i++ << ": return " << (**p).code_name() << ".p_string();\n"; } assert(i == 1 + m.independent().override().size() + 4 * m.size_dependent().raw().size()); for (Parameter_List::const_iterator p = m.independent().raw().begin(); p != m.independent().raw().end(); ++p) { out << " case " << i++ << ": return " << (**p).code_name() << ".string();\n"; } assert(i == 1 + m.independent().override().size() + 4 * m.size_dependent().raw().size() + m.independent().raw().size()); if (!m.hide_base()) { out << " default: return MODEL_" << m.inherit() << "::param_value(i);\n"; }else{ out << " default: return \"\";\n"; } out << " }\n" "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_model_is_valid(std::ofstream& out, const Model& m) { out << "bool MODEL_" << m.name() << "::is_valid(const COMPONENT* d)const\n" "{\n" " assert(d);\n"; if (m.validate().is_empty()) { out << " return MODEL_" << m.inherit() << "::is_valid(d);\n"; }else{ out << " const COMMON_" << m.dev_type() << "* c = dynamic_cast(d->common());\n" " if (!c) {\n" " return MODEL_" << m.inherit() << "::is_valid(d);\n" " }else{\n" " const MODEL_" << m.name() << "* m = this;" << m.validate() << " }\n"; } out << "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_tr_eval(std::ofstream& out, const Model& m) { out << "void MODEL_" << m.name() << "::tr_eval(COMPONENT*"; if (m.tr_eval().is_empty() && m.temperature().is_empty()) { out << ")const\n{untested();//425\n"; }else{ out << " brh)const\n{\n" " DEV_" << m.dev_type() << "* d = prechecked_cast(brh);\n" " assert(d);\n" " const COMMON_" << m.dev_type() << "* c = prechecked_cast(d->common());\n" " assert(c);\n" " const SDP_" << m.name() << "* s = prechecked_cast(c->sdp());\n" " assert(s);\n" " const MODEL_" << m.name() << "* m = this;\n"; if (!m.temperature().is_empty()) { out << " const TDP_" << m.name() << " T(d);\n" " const TDP_" << m.name() << "* t = &T;\n"; }else{ } out << m.tr_eval(); } out << "}\n" "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ void make_cc_model(std::ofstream& out, const Model& m) { out << "int MODEL_" << m.name() << "::_count = 0;\n" "/*--------------------------------------------------------------------------*/\n"; make_model_dispatcher(out, m); make_sdp_constructor(out, m); make_tdp_constructor(out, m); make_model_default_constructor(out, m); make_model_copy_constructor(out, m); make_model_dev_type(out, m); make_model_set_dev_type(out, m); make_model_precalc(out, m); make_model_new_sdp(out, m); make_model_set_param_by_index(out, m); make_model_param_is_printable(out, m); make_model_param_name(out, m); make_model_param_name_or_alias(out, m); make_model_param_value(out, m); make_model_is_valid(out, m); make_tr_eval(out, m); out << "/*--------------------------------------------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/mg_out_root.cc000066400000000000000000000071351145401216200155160ustar00rootroot00000000000000/*$Id: mg_out_root.cc,v 26.81 2008/05/27 05:33:43 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include "md.h" #include "mg_out.h" /*--------------------------------------------------------------------------*/ static void make_header(std::ofstream& out, const File& in, const std::string& dump_name) { out << in.head() << "/* This file is automatically generated. DO NOT EDIT */\n" << in.cc_headers() << "#include \"globals.h\"\n" "#include \"e_elemnt.h\"\n" "#include \"" << dump_name << ".h\"\n" "/*--------------------------------------" "------------------------------------*/\n" "const double NA(NOT_INPUT);\n" "const double INF(BIGBIG);\n" "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ static void make_tail(std::ofstream& out, const File& in) { out << in.cc_direct() << "/*--------------------------------------" "------------------------------------*/\n" "/*--------------------------------------" "------------------------------------*/\n"; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void make_cc_file(const File& in) { std::string dump_name = in.name(); { // chop suffix .model std::string::size_type loc = dump_name.rfind(".model"); if (loc == std::string::npos) { untested(); loc = dump_name.rfind(".vams"); }else{ } if (loc != std::string::npos) { dump_name.erase(loc); }else{ untested(); } } { // chop prefix path std::string::size_type loc = dump_name.find_last_of(ENDDIR); if (loc != std::string::npos) { dump_name.erase(0, loc+1); }else{ itested(); } } // open file std::ofstream out((dump_name+".cc").c_str()); if (!out) { untested(); os_error(dump_name); } make_header(out, in, dump_name); for (Model_List::const_iterator m = in.models().begin(); m != in.models().end(); ++m) { make_cc_model(out, **m); } for (Device_List::const_iterator m = in.devices().begin(); m != in.devices().end(); ++m) { out << "int DEV_" << (**m).name() << "::_count = -1;\n" "int COMMON_" << (**m).name() << "::_count = -1;\n" "static COMMON_" << (**m).name() << " Default_" << (**m).name() << "(CC_STATIC);\n" "/*--------------------------------------" "------------------------------------*/\n"; make_cc_common(out, **m); make_cc_dev(out, **m); } make_tail(out, in); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ modelgen/mode.h000066400000000000000000000056501145401216200137470ustar00rootroot00000000000000/*$Id: mode.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * several enumerated types to identify various modes */ //testing=script,complete 2006.07.14 #ifndef MODE_H #define MODE_H #include "io_.h" /*--------------------------------------------------------------------------*/ enum smode_t {moUNKNOWN=0, moANALOG=1, moDIGITAL, moMIXED}; inline OMSTREAM& operator<<(OMSTREAM& o, smode_t t) { const std::string s[] = {"unknown", "analog", "digital", "mixed"}; assert(t >= int(moUNKNOWN)); assert(t <= int(moMIXED)); return (o << s[t]); } enum SIM_MODE { // simulation types s_NONE, /* not doing anything, reset by cmd interpreter */ s_AC, /* AC analysis */ s_OP, /* op command */ s_DC, /* dc sweep command */ s_TRAN, /* transient command */ s_FOURIER /* fourier command */ }; const int sSTART = s_NONE; const int sCOUNT = s_FOURIER + 1; inline OMSTREAM& operator<<(OMSTREAM& o, SIM_MODE t) { const std::string s[] = {"ALL", "AC", "OP", "DC", "TRAN", "FOURIER"}; assert(t >= int(s_NONE)); assert(t <= int(s_FOURIER)); return (o << s[t]); } enum SIM_PHASE { // which of the many steps... p_NONE, /* not doing anything, reset by cmd interpreter */ p_INIT_DC, /* initial DC analysis */ p_DC_SWEEP, /* DC analysis sweep, in progress */ p_TRAN, /* transient, in progress */ p_RESTORE /* transient restore after stop */ }; enum PROBE_INDEX { // iter probes (continue after SIM_MODE) iPRINTSTEP = sCOUNT, /* iterations for this printed step */ iSTEP, /* iterations this internal step */ iTOTAL /* total iterations since startup */ }; const int iCOUNT = iTOTAL + 1; /* number of iteration counters */ /* control probes */ #define cSTEPCAUSE (0) /* what caused this time step */ #define cSTEPS (1) /* count of hidden steps (+ this unhidden) */ #define cCOUNT (2) /* number of control probes */ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif modelgen/patchlev.h000066400000000000000000000000531145401216200146210ustar00rootroot00000000000000#define PATCHLEVEL "2009.12.07 RCS 26.136" modelgen/u_opt.h000066400000000000000000000227571145401216200141600ustar00rootroot00000000000000/*$Id: u_opt.h,v 26.80 2008/05/27 02:18:47 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * all the options set by the .options card. */ //testing=script,complete 2006.07.14 #ifndef U_OPT_H #define U_OPT_H #include "mode.h" /*--------------------------------------------------------------------------*/ class CS; class LANGUAGE; /*--------------------------------------------------------------------------*/ /* integration method selector -- not all methods are implemented */ enum method_t {meUNKNOWN=0, // no method set meEULER, // backware Euler, unless forced to other meEULERONLY, // backward Euler only meTRAP, // usually trap, but euler where better meTRAPONLY, // always trapezoid meGEAR2, // usually gear2, but euler where better meGEAR2ONLY, // always gear2 (except breakpoints) meTRAPGEAR, // alt trap & gear2 meTRAPEULER, // alt trap & euler meNUM_METHODS}; // number of methods (array dimension) inline OMSTREAM& operator<<(OMSTREAM& o, method_t t) { const std::string s[] = {"unknown", "euler", "euleronly", "trap", "traponly", "gear2", "gear2only", "trapgear", "trapeuler"}; return (o << s[t]); } /*--------------------------------------------------------------------------*/ enum order_t {oREVERSE=1, oFORWARD, oAUTO}; inline OMSTREAM& operator<<(OMSTREAM& o, order_t t) { const std::string s[] = {"", "reverse", "forward", "auto"}; return (o << s[t]); } /*--------------------------------------------------------------------------*/ enum phase_t {pDEGREES, pRADIANS}; inline OMSTREAM& operator<<(OMSTREAM& o, phase_t t) { const std::string s[] = {"degrees", "radians"}; return (o << s[t]); } /*--------------------------------------------------------------------------*/ enum UNITS {uSI, uSPICE}; inline OMSTREAM& operator<<(OMSTREAM& o, UNITS t) { const std::string s[] = {"si", "spice"}; return (o << s[t]); } /*--------------------------------------------------------------------------*/ /* secant strategy is not implemented but it is a well known * method which may sometime be added */ #ifdef KNEECHORD enum strategy_t {stNEWTON, stKNEECHORD, stSECANT}; inline OMSTREAM& operator<<(OMSTREAM& o, strategy_t t) {untested(); const std::string s[] = {"newton", "kneechord", "secant"}; return (o << s[t]); } #endif /*--------------------------------------------------------------------------*/ enum {dsINIT=001, dsRANGE=002, dsDEVLIMIT=004, dsDEVREGION=010, dsREVERSE=020}; /*--------------------------------------------------------------------------*/ class INTERFACE OPT { private: explicit OPT(const OPT&) {unreachable(); incomplete();} public: explicit OPT() {} ~OPT() {} void command(CS& cmd); private: bool set_values(CS& cmd); void print(OMSTREAM& where); public: enum ITL {DCBIAS=1, DCXFER=2, TRLOW=3, TRHIGH=4, TRTOTAL=5, SSTEP=6, WCASE=7, TRACE=8, ITL_COUNT=9}; enum {_keep_time_steps = 5}; public: static bool acct; // flag: print accounting info static bool listing; // flag: print listing static bool mod; // flag: print models static bool page; // flag: do page ejects static bool node; // flag: print node table static bool opts; // flag: print options static double gmin; // minimum conductance allowed static double reltol; // relative error tolerance static double abstol; // absolute current error tolerance static double vntol; // absolute voltage error tolerance static double trtol; // transient error overestimation factor static double chgtol; // charge tolerance static double pivtol; // minimum acceptable pivot static double pivrel; // max to min ratio in a column? static int numdgt; // number of digits to display static double tnom_c; // nominal temperature static int cptime; // max allowed cpu time (seconds) static int limtim; // amt of time to reserve for plots static int limpts; // max points to print static int lvlcod; // enum: if == 2, solve fast static int lvltim; // enum: how to control time step static method_t method; // enum: integration method static int maxord; // max order of integration static double defl; // MOS default channel length static double defw; // MOS default channel width static double defad; // MOS default drain diffusion area static double defas; // MOS default source diffusion area static bool clobber; // allow to overwrite files without question static bool keys_between_nodes; // allow keywords between nodes static double floor; // display as zero if less than this static double vfloor; // display voltages as zero if less than this static double dampmax; // Newton-Raphson damping coefficient max static double dampmin; // Newton-Raphson damping coefficient min static int dampstrategy; // bit flags, damping strategy options static double roundofftol;// rel tolerance for zeroing after subtraction static double temp_c; // ambient temperature static double shortckt; // short resistance static int picky; // error picky-ness static unsigned outwidth; // width of output devices static double ydivisions; // plot divisions, y axis static phase_t phase; // how to print phase (degrees or radians) static order_t order; // ordering method static smode_t mode; // mixed-mode mode preference static int transits; // number of good transitions for digital static bool dupcheck; // check for duplicates on read static bool bypass; // bypass model evaluation, if appropriate static bool incmode; // make incremental changes to the matrix static bool lcbypass; // bypass L and C evaluation when appropriate static bool lubypass; // bypass parts of LU decomposition, if appropriate static bool fbbypass; // bypass fwd & back sub when last iter converged static bool traceload; // load only elements that need it, using queue static int itermin; // forced min iteration count. static double vmax; // + voltage limit for nonlinear calculations static double vmin; // - voltage limit for nonlinear calculations static double dtmin; // smallest internal step in transient analysis static double dtratio; // ratio of max / min dt in transient analysis static bool rstray; // include stray resistors in models static bool cstray; // include stray capacitors in models static int harmonics; // number of harmonics in fourier analysis static double trstepgrow; // limit of step size growth in transient analysis static double trstephold; // hold step size growth, converges slowly static double trstepshrink;// amt to shrink step size on convergence failure static double trreject; // how bad trunc error has to be to reject a step static int trsteporder; // interpolation order for step size control static double trstepcoef[_keep_time_steps]; // coefficient for step size control static bool showall; // flag: show development flags static int foooo; // a reusable value to aid development static int diodeflags; // convergence heuristic flags for diode static int mosflags; // convergence heuristic flags for mosfet static bool quitconvfail; // quit on convergence failure static bool edit; // use readline - command editing static int recursion; // max recursion depth static LANGUAGE* language; // simulation language static bool case_insensitive; static UNITS units; static double lowlim; // 1 - reltol static double uplim; // 1 + reltol static int itl[ITL_COUNT];// 1=dc (bias) iteration limit // 2=dc transfer iteration limit // 3=lower transient iteration limit // 4=upper transient iteration limit // 5=transient total iterations allowed // 6=source stepping iteration limit // 7=worst case iteration limit // 8=trace nonconvergence start iteration #ifdef KNEECHORD static strategy_t strategy; // What method we use to encourage non-linear devices to converge #endif }; /*--------------------------------------------------------------------------*/ class SET_RUN_MODE { private: RUN_MODE _old_run_mode; explicit SET_RUN_MODE() :_old_run_mode(ENV::run_mode) {unreachable();} public: explicit SET_RUN_MODE(RUN_MODE rm) :_old_run_mode(ENV::run_mode) { //std::cout << ENV::run_mode << '^' << rm << '\n'; ENV::run_mode = rm; } ~SET_RUN_MODE() { //std::cout << ENV::run_mode << 'v' << _old_run_mode << '\n'; ENV::run_mode = _old_run_mode; } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif modelgen/u_opt1.cc000066400000000000000000000074131145401216200143670ustar00rootroot00000000000000/*$Id: u_opt1.cc,v 26.80 2008/05/27 02:18:47 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * all the options set by the .options card. * initialization and declaration of statics */ //testing=trivial 2006.07.17 #include "u_opt.h" bool OPT::acct = false; bool OPT::listing = false; bool OPT::mod = true; bool OPT::page = false; bool OPT::node = false; bool OPT::opts = false; double OPT::gmin = 1e-12; double OPT::reltol = .001; double OPT::abstol = 1e-12; double OPT::vntol = 1e-6; double OPT::trtol = 7.0; double OPT::chgtol = 1e-14; double OPT::pivtol = 1e-13; double OPT::pivrel = 1e-3; int OPT::numdgt = 5; double OPT::tnom_c = 27.0; int OPT::cptime = 30000; int OPT::limtim = 2; int OPT::limpts = 201; int OPT::lvlcod = 2; int OPT::lvltim = 2; method_t OPT::method = meTRAP; int OPT::maxord = 2; double OPT::defl = 100e-6; double OPT::defw = 100e-6; double OPT::defad = 0.; double OPT::defas = 0.; bool OPT::clobber = true; bool OPT::keys_between_nodes = true; double OPT::dampmax = 1.0; double OPT::dampmin = 0.5; int OPT::dampstrategy = 0; //dsINIT|dsDEVREGION|dsREVERSE; double OPT::floor = 1e-21; double OPT::vfloor = 1e-15; double OPT::roundofftol = 1e-13; double OPT::temp_c = 27.0; double OPT::shortckt = 10e-6; int OPT::picky = bPICKY; unsigned OPT::outwidth = 9999; double OPT::ydivisions = 4.; phase_t OPT::phase = pDEGREES; order_t OPT::order = oAUTO; smode_t OPT::mode = moMIXED; int OPT::transits = 2; bool OPT::dupcheck = false; bool OPT::bypass = true; bool OPT::incmode = true; bool OPT::lcbypass = true; bool OPT::lubypass = true; bool OPT::fbbypass = true; bool OPT::traceload = true; int OPT::itermin = 1; double OPT::vmax = 5; double OPT::vmin = -5; double OPT::dtmin = 1e-12; double OPT::dtratio = 1e9; bool OPT::rstray = true; bool OPT::cstray = true; int OPT::harmonics = 9; double OPT::trstepgrow = 1e99; double OPT::trstephold = 1e99; double OPT::trstepshrink = 2.; /* spice is fixed at 8 */ double OPT::trreject = .5; int OPT::trsteporder = 3; double OPT::trstepcoef[_keep_time_steps] = {1., 1./4., 1./24., 1./192.}; bool OPT::showall = false; int OPT::foooo = 0; int OPT::diodeflags = 0; int OPT::mosflags = 0; bool OPT::quitconvfail = false; bool OPT::edit = true; int OPT::recursion = 20; LANGUAGE* OPT::language = NULL; bool OPT::case_insensitive = false; UNITS OPT::units = uSI; double OPT::lowlim = 1. - OPT::reltol; double OPT::uplim = 1. + OPT::reltol; int OPT::itl[OPT::ITL_COUNT] = { 100, /* 0=dummy */ 100, /* 1=dc (bias) iteration limit */ 50, /* 2=dc transfer iteration limit */ 6, /* 3=lower transient iteration limit (spice is 4) */ 20, /* 4=upper transient iteration limit (spice is 10) */ 5000, /* 5=transient total iterations allowed */ 0, /* 6=source stepping iteration limit */ 1, /* 7=worst case iteration limit */ 99 /* 8=trace nonconvergence start iteration */ }; #ifdef KNEECHORD strategy_t OPT::strategy = stNEWTON; /* Default is Newton's Method, fastest */ #endif src/000077500000000000000000000000001145401216200116415ustar00rootroot00000000000000src/Make.depend000066400000000000000000001010231145401216200136740ustar00rootroot00000000000000d_mos1.o: d_mos1.cc globals.h l_dispatcher.h l_stlextra.h md.h io_trace.h \ io_error.h u_opt.h mode.h io_.h l_lib.h ap.h e_elemnt.h e_node.h \ u_sim_data.h constant.h l_compar.h m_matrix.h e_base.h m_cpoly.h \ l_denoise.h e_compon.h u_time_pair.h u_parameter.h m_expression.h \ m_base.h e_cardlist.h e_card.h d_mos1.h d_mos123.h d_mos_base.h d_mos.h \ d_diode.h u_sdp.h e_subckt.h e_model.h d_mos2.o: d_mos2.cc l_compar.h md.h io_trace.h io_error.h l_denoise.h \ u_opt.h mode.h io_.h l_lib.h globals.h l_dispatcher.h l_stlextra.h ap.h \ e_elemnt.h e_node.h u_sim_data.h constant.h m_matrix.h e_base.h \ m_cpoly.h e_compon.h u_time_pair.h u_parameter.h m_expression.h m_base.h \ e_cardlist.h e_card.h d_mos2.h d_mos123.h d_mos_base.h d_mos.h d_diode.h \ u_sdp.h e_subckt.h e_model.h d_mos3.o: d_mos3.cc l_denoise.h u_opt.h mode.h io_.h l_lib.h md.h \ io_trace.h io_error.h globals.h l_dispatcher.h l_stlextra.h ap.h \ e_elemnt.h e_node.h u_sim_data.h constant.h l_compar.h m_matrix.h \ e_base.h m_cpoly.h e_compon.h u_time_pair.h u_parameter.h m_expression.h \ m_base.h e_cardlist.h e_card.h d_mos3.h d_mos123.h d_mos_base.h d_mos.h \ d_diode.h u_sdp.h e_subckt.h e_model.h d_mos4.o: d_mos4.cc globals.h l_dispatcher.h l_stlextra.h md.h io_trace.h \ io_error.h u_opt.h mode.h io_.h l_lib.h ap.h e_elemnt.h e_node.h \ u_sim_data.h constant.h l_compar.h m_matrix.h e_base.h m_cpoly.h \ l_denoise.h e_compon.h u_time_pair.h u_parameter.h m_expression.h \ m_base.h e_cardlist.h e_card.h d_mos4.h d_mos_base.h d_mos.h d_diode.h \ u_sdp.h e_subckt.h e_model.h d_mos5.o: d_mos5.cc globals.h l_dispatcher.h l_stlextra.h md.h io_trace.h \ io_error.h u_opt.h mode.h io_.h l_lib.h ap.h e_elemnt.h e_node.h \ u_sim_data.h constant.h l_compar.h m_matrix.h e_base.h m_cpoly.h \ l_denoise.h e_compon.h u_time_pair.h u_parameter.h m_expression.h \ m_base.h e_cardlist.h e_card.h d_mos5.h d_mos_base.h d_mos.h d_diode.h \ u_sdp.h e_subckt.h e_model.h d_mos6.o: d_mos6.cc l_denoise.h u_opt.h mode.h io_.h l_lib.h md.h \ io_trace.h io_error.h globals.h l_dispatcher.h l_stlextra.h ap.h \ e_elemnt.h e_node.h u_sim_data.h constant.h l_compar.h m_matrix.h \ e_base.h m_cpoly.h e_compon.h u_time_pair.h u_parameter.h m_expression.h \ m_base.h e_cardlist.h e_card.h d_mos6.h d_mos123.h d_mos_base.h d_mos.h \ d_diode.h u_sdp.h e_subckt.h e_model.h d_mos7.o: d_mos7.cc l_compar.h md.h io_trace.h io_error.h l_denoise.h \ u_opt.h mode.h io_.h l_lib.h globals.h l_dispatcher.h l_stlextra.h ap.h \ e_elemnt.h e_node.h u_sim_data.h constant.h m_matrix.h e_base.h \ m_cpoly.h e_compon.h u_time_pair.h u_parameter.h m_expression.h m_base.h \ e_cardlist.h e_card.h d_mos7.h d_mos_base.h d_mos.h d_diode.h u_sdp.h \ e_subckt.h e_model.h d_mos8.o: d_mos8.cc l_compar.h md.h io_trace.h io_error.h l_denoise.h \ u_opt.h mode.h io_.h l_lib.h globals.h l_dispatcher.h l_stlextra.h ap.h \ e_elemnt.h e_node.h u_sim_data.h constant.h m_matrix.h e_base.h \ m_cpoly.h e_compon.h u_time_pair.h u_parameter.h m_expression.h m_base.h \ e_cardlist.h e_card.h d_mos8.h d_mos_base.h d_mos.h d_diode.h u_sdp.h \ e_subckt.h e_model.h d_mos123.o: d_mos123.cc globals.h l_dispatcher.h l_stlextra.h md.h \ io_trace.h io_error.h u_opt.h mode.h io_.h l_lib.h ap.h e_elemnt.h \ e_node.h u_sim_data.h constant.h l_compar.h m_matrix.h e_base.h \ m_cpoly.h l_denoise.h e_compon.h u_time_pair.h u_parameter.h \ m_expression.h m_base.h e_cardlist.h e_card.h d_mos123.h d_mos_base.h \ d_mos.h d_diode.h u_sdp.h e_subckt.h e_model.h d_mos_base.o: d_mos_base.cc globals.h l_dispatcher.h l_stlextra.h md.h \ io_trace.h io_error.h u_opt.h mode.h io_.h l_lib.h ap.h e_elemnt.h \ e_node.h u_sim_data.h constant.h l_compar.h m_matrix.h e_base.h \ m_cpoly.h l_denoise.h e_compon.h u_time_pair.h u_parameter.h \ m_expression.h m_base.h e_cardlist.h e_card.h d_mos_base.h d_mos.h \ d_diode.h u_sdp.h e_subckt.h e_model.h d_mos.o: d_mos.cc u_limit.h md.h io_trace.h io_error.h e_storag.h \ e_elemnt.h e_node.h u_sim_data.h constant.h l_compar.h u_opt.h mode.h \ io_.h l_lib.h m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h \ e_compon.h u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h e_card.h d_mos_base.h d_mos.h \ d_diode.h u_sdp.h e_subckt.h e_model.h d_bjt.o: d_bjt.cc u_limit.h md.h io_trace.h io_error.h globals.h \ l_dispatcher.h l_stlextra.h u_opt.h mode.h io_.h l_lib.h ap.h e_elemnt.h \ e_node.h u_sim_data.h constant.h l_compar.h m_matrix.h e_base.h \ m_cpoly.h l_denoise.h e_compon.h u_time_pair.h u_parameter.h \ m_expression.h m_base.h e_cardlist.h e_card.h d_bjt.h d_diode.h u_sdp.h \ e_subckt.h e_model.h d_diode.o: d_diode.cc e_aux.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h e_storag.h e_elemnt.h m_cpoly.h l_denoise.h \ e_compon.h u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h e_card.h d_diode.h u_sdp.h \ e_subckt.h e_model.h d_admit.o: d_admit.cc e_elemnt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_card.h d_cap.o: d_cap.cc e_storag.h e_elemnt.h e_node.h u_sim_data.h constant.h \ md.h io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h \ m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h \ u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h \ m_base.h e_cardlist.h e_card.h d_cccs.o: d_cccs.cc e_ccsrc.h e_elemnt.h e_node.h u_sim_data.h constant.h \ md.h io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h \ m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h \ u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h \ m_base.h e_cardlist.h e_card.h d_ccvs.o: d_ccvs.cc e_ccsrc.h e_elemnt.h e_node.h u_sim_data.h constant.h \ md.h io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h \ m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h \ u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h \ m_base.h e_cardlist.h e_card.h d_coil.o: d_coil.cc e_subckt.h e_compon.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h e_card.h e_base.h e_ccsrc.h \ e_elemnt.h e_node.h m_cpoly.h l_denoise.h e_storag.h d_cs.o: d_cs.cc e_elemnt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_card.h d_poly_g.o: d_poly_g.cc e_elemnt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_card.h d_poly_cap.o: d_poly_cap.cc e_storag.h e_elemnt.h e_node.h u_sim_data.h \ constant.h md.h io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h \ l_lib.h m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h \ e_compon.h u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h e_card.h d_res.o: d_res.cc e_elemnt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_card.h d_switch.o: d_switch.cc e_model.h u_parameter.h globals.h l_dispatcher.h \ l_stlextra.h md.h io_trace.h io_error.h u_opt.h mode.h io_.h l_lib.h \ ap.h m_expression.h m_base.h constant.h e_cardlist.h e_card.h e_base.h \ e_elemnt.h e_node.h u_sim_data.h l_compar.h m_matrix.h m_cpoly.h \ l_denoise.h e_compon.h u_time_pair.h d_trln.o: d_trln.cc m_wave.h l_denoise.h u_opt.h mode.h io_.h l_lib.h \ md.h io_trace.h io_error.h m_interp.h m_cpoly.h constant.h e_elemnt.h \ e_node.h u_sim_data.h l_compar.h m_matrix.h l_stlextra.h e_base.h \ e_compon.h u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h e_card.h d_vcg.o: d_vcg.cc e_elemnt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_card.h d_vcr.o: d_vcr.cc e_elemnt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_card.h d_vcvs.o: d_vcvs.cc e_elemnt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_card.h d_vs.o: d_vs.cc e_elemnt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_card.h bm_complex.o: bm_complex.cc e_elemnt.h e_node.h u_sim_data.h constant.h \ md.h io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h \ m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h \ u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h \ m_base.h e_cardlist.h e_card.h bm.h bm_cond.o: bm_cond.cc e_elemnt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_card.h bm.h bm_exp.o: bm_exp.cc e_elemnt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_card.h u_lang.h bm.h bm_fit.o: bm_fit.cc u_lang.h u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h e_elemnt.h e_node.h u_sim_data.h constant.h l_compar.h \ m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h \ u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h \ m_base.h e_cardlist.h e_card.h m_spline.h bm.h bm_generator.o: bm_generator.cc e_elemnt.h e_node.h u_sim_data.h \ constant.h md.h io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h \ l_lib.h m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h \ e_compon.h u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h e_card.h bm.h bm_model.o: bm_model.cc e_model.h u_parameter.h globals.h l_dispatcher.h \ l_stlextra.h md.h io_trace.h io_error.h u_opt.h mode.h io_.h l_lib.h \ ap.h m_expression.h m_base.h constant.h e_cardlist.h e_card.h e_base.h \ bm.h e_compon.h u_sim_data.h l_compar.h m_matrix.h u_time_pair.h bm_poly.o: bm_poly.cc u_lang.h u_opt.h mode.h io_.h l_lib.h md.h \ io_trace.h io_error.h e_elemnt.h e_node.h u_sim_data.h constant.h \ l_compar.h m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h \ e_compon.h u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h e_card.h bm.h bm_posy.o: bm_posy.cc u_lang.h u_opt.h mode.h io_.h l_lib.h md.h \ io_trace.h io_error.h e_elemnt.h e_node.h u_sim_data.h constant.h \ l_compar.h m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h \ e_compon.h u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h e_card.h bm.h bm_pulse.o: bm_pulse.cc e_elemnt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_card.h u_lang.h bm.h bm_pwl.o: bm_pwl.cc u_lang.h u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h e_elemnt.h e_node.h u_sim_data.h constant.h l_compar.h \ m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h \ u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h \ m_base.h e_cardlist.h e_card.h m_interp.h bm.h bm_sffm.o: bm_sffm.cc e_elemnt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_card.h u_lang.h bm.h bm_sin.o: bm_sin.cc e_elemnt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_card.h u_lang.h bm.h bm_tanh.o: bm_tanh.cc u_lang.h u_opt.h mode.h io_.h l_lib.h md.h \ io_trace.h io_error.h e_elemnt.h e_node.h u_sim_data.h constant.h \ l_compar.h m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h \ e_compon.h u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h e_card.h bm.h bmm_table.o: bmm_table.cc u_lang.h u_opt.h mode.h io_.h l_lib.h md.h \ io_trace.h io_error.h e_elemnt.h e_node.h u_sim_data.h constant.h \ l_compar.h m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h \ e_compon.h u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h e_card.h m_spline.h e_model.h bm.h bmm_semi.o: bmm_semi.cc u_lang.h u_opt.h mode.h io_.h l_lib.h md.h \ io_trace.h io_error.h e_model.h u_parameter.h globals.h l_dispatcher.h \ l_stlextra.h ap.h m_expression.h m_base.h constant.h e_cardlist.h \ e_card.h e_base.h bm.h e_compon.h u_sim_data.h l_compar.h m_matrix.h \ u_time_pair.h c_clear.o: c_clear.cc c_comand.h e_card.h e_base.h md.h io_trace.h \ io_error.h globals.h l_dispatcher.h l_stlextra.h u_opt.h mode.h io_.h \ l_lib.h ap.h c_comand.o: c_comand.cc constant.h md.h io_trace.h io_error.h c_comand.h \ e_card.h e_base.h globals.h l_dispatcher.h l_stlextra.h u_opt.h mode.h \ io_.h l_lib.h ap.h c_delete.o: c_delete.cc d_subckt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h e_subckt.h e_compon.h u_time_pair.h u_parameter.h \ globals.h l_dispatcher.h ap.h m_expression.h m_base.h e_cardlist.h \ e_card.h c_comand.h c_exp.o: c_exp.cc globals.h l_dispatcher.h l_stlextra.h md.h io_trace.h \ io_error.h u_opt.h mode.h io_.h l_lib.h ap.h m_expression.h m_base.h \ constant.h c_comand.h e_card.h e_base.h c_list.o: c_list.cc e_cardlist.h md.h io_trace.h io_error.h u_lang.h \ u_opt.h mode.h io_.h l_lib.h c_comand.h e_card.h e_base.h globals.h \ l_dispatcher.h l_stlextra.h ap.h c_measure.o: c_measure.cc u_parameter.h globals.h l_dispatcher.h \ l_stlextra.h md.h io_trace.h io_error.h u_opt.h mode.h io_.h l_lib.h \ ap.h m_expression.h m_base.h constant.h e_cardlist.h u_function.h \ c_comand.h e_card.h e_base.h c_modify.o: c_modify.cc e_elemnt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_card.h u_cardst.h c_comand.h c_param.o: c_param.cc c_comand.h e_card.h e_base.h md.h io_trace.h \ io_error.h u_parameter.h globals.h l_dispatcher.h l_stlextra.h u_opt.h \ mode.h io_.h l_lib.h ap.h m_expression.h m_base.h constant.h \ e_cardlist.h c_prbcmd.o: c_prbcmd.cc u_sim_data.h constant.h md.h io_trace.h \ io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h c_comand.h e_card.h e_base.h u_prblst.h u_probe.h globals.h \ l_dispatcher.h ap.h c_status.o: c_status.cc u_sim_data.h constant.h md.h io_trace.h \ io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h u_status.h l_timer.h c_comand.h e_card.h e_base.h globals.h \ l_dispatcher.h ap.h c_sweep.o: c_sweep.cc c_comand.h e_card.h e_base.h md.h io_trace.h \ io_error.h globals.h l_dispatcher.h l_stlextra.h u_opt.h mode.h io_.h \ l_lib.h ap.h c_sim.o: c_sim.cc u_sim_data.h constant.h md.h io_trace.h io_error.h \ l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h l_stlextra.h \ c_comand.h e_card.h e_base.h globals.h l_dispatcher.h ap.h c_system.o: c_system.cc c_comand.h e_card.h e_base.h md.h io_trace.h \ io_error.h globals.h l_dispatcher.h l_stlextra.h u_opt.h mode.h io_.h \ l_lib.h ap.h s_ac.o: s_ac.cc u_sim_data.h constant.h md.h io_trace.h io_error.h \ l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h l_stlextra.h \ u_status.h l_timer.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h u_prblst.h u_probe.h s__.h \ c_comand.h e_card.h e_base.h s_dc.o: s_dc.cc u_status.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h l_timer.h u_prblst.h u_probe.h l_compar.h u_cardst.h \ e_compon.h u_sim_data.h constant.h u_opt.h m_matrix.h l_stlextra.h \ u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h \ m_base.h e_cardlist.h e_card.h e_base.h e_elemnt.h e_node.h m_cpoly.h \ l_denoise.h s__.h c_comand.h s_fo.o: s_fo.cc u_sim_data.h constant.h md.h io_trace.h io_error.h \ l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h l_stlextra.h \ u_status.h l_timer.h m_phase.h declare.h u_prblst.h u_probe.h s_tr.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h s__.h c_comand.h e_card.h e_base.h s_tr.o: s_tr.cc u_sim_data.h constant.h md.h io_trace.h io_error.h \ l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h l_stlextra.h \ u_status.h l_timer.h s_tr.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h s__.h c_comand.h e_card.h e_base.h s_tr_set.o: s_tr_set.cc u_sim_data.h constant.h md.h io_trace.h \ io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h u_prblst.h u_probe.h ap.h s_tr.h u_parameter.h globals.h \ l_dispatcher.h m_expression.h m_base.h e_cardlist.h s__.h c_comand.h \ e_card.h e_base.h s_tr_swp.o: s_tr_swp.cc u_time_pair.h constant.h md.h io_trace.h \ io_error.h u_sim_data.h l_compar.h u_opt.h mode.h io_.h l_lib.h \ m_matrix.h l_stlextra.h u_status.h l_timer.h declare.h s_tr.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h s__.h c_comand.h e_card.h e_base.h lang_spice.o: lang_spice.cc u_status.h mode.h io_.h l_lib.h md.h \ io_trace.h io_error.h l_timer.h c_comand.h e_card.h e_base.h d_dot.h \ d_coment.h d_subckt.h e_node.h u_sim_data.h constant.h l_compar.h \ u_opt.h m_matrix.h l_stlextra.h e_subckt.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h u_lang.h d_logic.h e_model.h e_elemnt.h m_cpoly.h \ l_denoise.h bm.h lang_spectre.o: lang_spectre.cc c_comand.h e_card.h e_base.h md.h \ io_trace.h io_error.h d_dot.h d_coment.h d_subckt.h e_node.h \ u_sim_data.h constant.h l_compar.h u_opt.h mode.h io_.h l_lib.h \ m_matrix.h l_stlextra.h e_subckt.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_model.h u_lang.h lang_verilog.o: lang_verilog.cc c_comand.h e_card.h e_base.h md.h \ io_trace.h io_error.h d_dot.h d_coment.h d_subckt.h e_node.h \ u_sim_data.h constant.h l_compar.h u_opt.h mode.h io_.h l_lib.h \ m_matrix.h l_stlextra.h e_subckt.h e_compon.h u_time_pair.h \ u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h m_base.h \ e_cardlist.h e_model.h u_lang.h func_core.o: func_core.cc u_parameter.h globals.h l_dispatcher.h \ l_stlextra.h md.h io_trace.h io_error.h u_opt.h mode.h io_.h l_lib.h \ ap.h m_expression.h m_base.h constant.h e_cardlist.h u_function.h measure_eval.o: measure_eval.cc u_parameter.h globals.h l_dispatcher.h \ l_stlextra.h md.h io_trace.h io_error.h u_opt.h mode.h io_.h l_lib.h \ ap.h m_expression.h m_base.h constant.h e_cardlist.h u_function.h measure_max.o: measure_max.cc u_parameter.h globals.h l_dispatcher.h \ l_stlextra.h md.h io_trace.h io_error.h u_opt.h mode.h io_.h l_lib.h \ ap.h m_expression.h m_base.h constant.h e_cardlist.h m_wave.h \ l_denoise.h m_interp.h m_cpoly.h u_function.h measure_min.o: measure_min.cc u_parameter.h globals.h l_dispatcher.h \ l_stlextra.h md.h io_trace.h io_error.h u_opt.h mode.h io_.h l_lib.h \ ap.h m_expression.h m_base.h constant.h e_cardlist.h m_wave.h \ l_denoise.h m_interp.h m_cpoly.h u_function.h measure_slewrate.o: measure_slewrate.cc l_compar.h md.h io_trace.h \ io_error.h u_parameter.h globals.h l_dispatcher.h l_stlextra.h u_opt.h \ mode.h io_.h l_lib.h ap.h m_expression.h m_base.h constant.h \ e_cardlist.h m_wave.h l_denoise.h m_interp.h m_cpoly.h u_function.h measure_cross.o: measure_cross.cc u_parameter.h globals.h l_dispatcher.h \ l_stlextra.h md.h io_trace.h io_error.h u_opt.h mode.h io_.h l_lib.h \ ap.h m_expression.h m_base.h constant.h e_cardlist.h m_wave.h \ l_denoise.h m_interp.h m_cpoly.h u_function.h measure_integral.o: measure_integral.cc u_parameter.h globals.h \ l_dispatcher.h l_stlextra.h md.h io_trace.h io_error.h u_opt.h mode.h \ io_.h l_lib.h ap.h m_expression.h m_base.h constant.h e_cardlist.h \ m_wave.h l_denoise.h m_interp.h m_cpoly.h u_function.h measure_average.o: measure_average.cc u_parameter.h globals.h \ l_dispatcher.h l_stlextra.h md.h io_trace.h io_error.h u_opt.h mode.h \ io_.h l_lib.h ap.h m_expression.h m_base.h constant.h e_cardlist.h \ m_wave.h l_denoise.h m_interp.h m_cpoly.h u_function.h measure_rms.o: measure_rms.cc u_parameter.h globals.h l_dispatcher.h \ l_stlextra.h md.h io_trace.h io_error.h u_opt.h mode.h io_.h l_lib.h \ ap.h m_expression.h m_base.h constant.h e_cardlist.h m_wave.h \ l_denoise.h m_interp.h m_cpoly.h u_function.h measure_at.o: measure_at.cc u_parameter.h globals.h l_dispatcher.h \ l_stlextra.h md.h io_trace.h io_error.h u_opt.h mode.h io_.h l_lib.h \ ap.h m_expression.h m_base.h constant.h e_cardlist.h m_wave.h \ l_denoise.h m_interp.h m_cpoly.h u_function.h m_expression_dump.o: m_expression_dump.cc m_expression.h m_base.h l_lib.h \ md.h io_trace.h io_error.h ap.h constant.h m_expression_in.o: m_expression_in.cc m_expression.h m_base.h l_lib.h \ md.h io_trace.h io_error.h ap.h constant.h m_expression_reduce.o: m_expression_reduce.cc u_function.h md.h \ io_trace.h io_error.h u_parameter.h globals.h l_dispatcher.h \ l_stlextra.h u_opt.h mode.h io_.h l_lib.h ap.h m_expression.h m_base.h \ constant.h e_cardlist.h m_base_in.o: m_base_in.cc m_base.h l_lib.h md.h io_trace.h io_error.h \ ap.h constant.h m_base_math.o: m_base_math.cc m_base.h l_lib.h md.h io_trace.h io_error.h \ ap.h constant.h m_fft.o: m_fft.cc constant.h md.h io_trace.h io_error.h declare.h m_spline.o: m_spline.cc m_cpoly.h constant.h md.h io_trace.h io_error.h \ l_denoise.h u_opt.h mode.h io_.h l_lib.h m_spline.h u_parameter.h \ globals.h l_dispatcher.h l_stlextra.h ap.h m_expression.h m_base.h \ e_cardlist.h ap_construct.o: ap_construct.cc u_opt.h mode.h io_.h l_lib.h md.h \ io_trace.h io_error.h ap.h ap_convert.o: ap_convert.cc u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h ap.h ap_error.o: ap_error.cc u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h ap.h ap_get.o: ap_get.cc ap.h md.h io_trace.h io_error.h ap_match.o: ap_match.cc u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h ap.h ap_skip.o: ap_skip.cc ap.h md.h io_trace.h io_error.h l_ftos.o: l_ftos.cc l_lib.h md.h io_trace.h io_error.h constant.h l_pmatch.o: l_pmatch.cc ap.h md.h io_trace.h io_error.h l_lib.h l_timer.o: l_timer.cc l_timer.h io_.h l_lib.h md.h io_trace.h io_error.h l_trim.o: l_trim.cc l_wmatch.o: l_wmatch.cc u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h io.o: io.cc io_.h l_lib.h md.h io_trace.h io_error.h io_contr.o: io_contr.cc io_.h l_lib.h md.h io_trace.h io_error.h ap.h io_error.o: io_error.cc ap.h md.h io_trace.h io_error.h u_opt.h mode.h \ io_.h l_lib.h io_findf.o: io_findf.cc l_lib.h md.h io_trace.h io_error.h io_out.o: io_out.cc u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h io_xopen.o: io_xopen.cc u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h constant.h ap.h u_function.o: u_function.cc e_base.h md.h io_trace.h io_error.h \ u_function.h u_lang.o: u_lang.cc c_comand.h e_card.h e_base.h md.h io_trace.h \ io_error.h d_dot.h d_coment.h d_subckt.h e_node.h u_sim_data.h \ constant.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_subckt.h e_compon.h u_time_pair.h u_parameter.h globals.h \ l_dispatcher.h ap.h m_expression.h m_base.h e_cardlist.h e_model.h \ u_lang.h u_nodemap.o: u_nodemap.cc e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h u_nodemap.h u_opt1.o: u_opt1.cc u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h u_opt2.o: u_opt2.cc u_lang.h u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h l_compar.h ap.h u_parameter.o: u_parameter.cc l_stlextra.h md.h io_trace.h io_error.h \ u_parameter.h globals.h l_dispatcher.h u_opt.h mode.h io_.h l_lib.h ap.h \ m_expression.h m_base.h constant.h e_cardlist.h u_lang.h u_prblst.o: u_prblst.cc e_cardlist.h md.h io_trace.h io_error.h e_node.h \ u_sim_data.h constant.h l_compar.h u_opt.h mode.h io_.h l_lib.h \ m_matrix.h l_stlextra.h e_base.h e_card.h u_nodemap.h ap.h u_prblst.h \ u_probe.h u_probe.o: u_probe.cc u_sim_data.h constant.h md.h io_trace.h io_error.h \ l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h l_stlextra.h \ u_status.h l_timer.h e_base.h u_probe.h u_sim_data.o: u_sim_data.cc e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h u_nodemap.h e_cardlist.h u_status.h l_timer.h u_xprobe.o: u_xprobe.cc m_phase.h constant.h md.h io_trace.h io_error.h \ u_opt.h mode.h io_.h l_lib.h u_xprobe.h s__init.o: s__init.cc u_status.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h l_timer.h u_sim_data.h constant.h l_compar.h u_opt.h \ m_matrix.h l_stlextra.h s__.h c_comand.h e_card.h e_base.h s__out.o: s__out.cc u_sim_data.h constant.h md.h io_trace.h io_error.h \ l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h l_stlextra.h \ u_status.h l_timer.h m_wave.h l_denoise.h m_interp.h m_cpoly.h \ u_prblst.h u_probe.h declare.h s__.h c_comand.h e_card.h e_base.h s__solve.o: s__solve.cc e_cardlist.h md.h io_trace.h io_error.h \ u_status.h mode.h io_.h l_lib.h l_timer.h e_node.h u_sim_data.h \ constant.h l_compar.h u_opt.h m_matrix.h l_stlextra.h e_base.h s__.h \ c_comand.h e_card.h d_subckt.o: d_subckt.cc d_subckt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h e_subckt.h e_compon.h u_time_pair.h u_parameter.h \ globals.h l_dispatcher.h ap.h m_expression.h m_base.h e_cardlist.h \ e_card.h d_logic.o: d_logic.cc d_subckt.h e_node.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h e_base.h e_subckt.h e_compon.h u_time_pair.h u_parameter.h \ globals.h l_dispatcher.h ap.h m_expression.h m_base.h e_cardlist.h \ e_card.h u_xprobe.h d_logic.h e_model.h e_elemnt.h m_cpoly.h l_denoise.h d_logicmod.o: d_logicmod.cc d_logic.h e_model.h u_parameter.h globals.h \ l_dispatcher.h l_stlextra.h md.h io_trace.h io_error.h u_opt.h mode.h \ io_.h l_lib.h ap.h m_expression.h m_base.h constant.h e_cardlist.h \ e_card.h e_base.h e_elemnt.h e_node.h u_sim_data.h l_compar.h m_matrix.h \ m_cpoly.h l_denoise.h e_compon.h u_time_pair.h e_base.o: e_base.cc u_sim_data.h constant.h md.h io_trace.h io_error.h \ l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h l_stlextra.h m_wave.h \ l_denoise.h m_interp.h m_cpoly.h u_prblst.h u_probe.h u_xprobe.h \ e_base.h e_card.o: e_card.cc u_time_pair.h constant.h md.h io_trace.h io_error.h \ e_cardlist.h e_node.h u_sim_data.h l_compar.h u_opt.h mode.h io_.h \ l_lib.h m_matrix.h l_stlextra.h e_base.h e_card.h e_node.o: e_node.cc u_nodemap.h md.h io_trace.h io_error.h d_logic.h \ e_model.h u_parameter.h globals.h l_dispatcher.h l_stlextra.h u_opt.h \ mode.h io_.h l_lib.h ap.h m_expression.h m_base.h constant.h \ e_cardlist.h e_card.h e_base.h e_elemnt.h e_node.h u_sim_data.h \ l_compar.h m_matrix.h m_cpoly.h l_denoise.h e_compon.h u_time_pair.h \ e_aux.h u_xprobe.h e_model.o: e_model.cc e_compon.h u_sim_data.h constant.h md.h io_trace.h \ io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h e_card.h e_base.h e_model.h e_compon.o: e_compon.cc u_lang.h u_opt.h mode.h io_.h l_lib.h md.h \ io_trace.h io_error.h e_model.h u_parameter.h globals.h l_dispatcher.h \ l_stlextra.h ap.h m_expression.h m_base.h constant.h e_cardlist.h \ e_card.h e_base.h e_elemnt.h e_node.h u_sim_data.h l_compar.h m_matrix.h \ m_cpoly.h l_denoise.h e_compon.h u_time_pair.h e_elemnt.o: e_elemnt.cc m_divdiff.h u_xprobe.h constant.h md.h io_trace.h \ io_error.h e_aux.h e_node.h u_sim_data.h l_compar.h u_opt.h mode.h io_.h \ l_lib.h m_matrix.h l_stlextra.h e_base.h e_elemnt.h m_cpoly.h \ l_denoise.h e_compon.h u_time_pair.h u_parameter.h globals.h \ l_dispatcher.h ap.h m_expression.h m_base.h e_cardlist.h e_card.h e_ccsrc.o: e_ccsrc.cc e_ccsrc.h e_elemnt.h e_node.h u_sim_data.h \ constant.h md.h io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h \ l_lib.h m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h \ e_compon.h u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h e_card.h e_storag.o: e_storag.cc e_storag.h e_elemnt.h e_node.h u_sim_data.h \ constant.h md.h io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h \ l_lib.h m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h \ e_compon.h u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h e_card.h e_cardlist.o: e_cardlist.cc u_time_pair.h constant.h md.h io_trace.h \ io_error.h e_node.h u_sim_data.h l_compar.h u_opt.h mode.h io_.h l_lib.h \ m_matrix.h l_stlextra.h e_base.h u_nodemap.h e_model.h u_parameter.h \ globals.h l_dispatcher.h ap.h m_expression.h m_base.h e_cardlist.h \ e_card.h bm_value.o: bm_value.cc bm.h e_compon.h u_sim_data.h constant.h md.h \ io_trace.h io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h \ m_expression.h m_base.h e_cardlist.h e_card.h e_base.h bm.o: bm.cc u_lang.h u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h e_elemnt.h e_node.h u_sim_data.h constant.h l_compar.h \ m_matrix.h l_stlextra.h e_base.h m_cpoly.h l_denoise.h e_compon.h \ u_time_pair.h u_parameter.h globals.h l_dispatcher.h ap.h m_expression.h \ m_base.h e_cardlist.h e_card.h bm.h c__cmd.o: c__cmd.cc u_status.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h l_timer.h declare.h c_comand.h e_card.h e_base.h globals.h \ l_dispatcher.h l_stlextra.h u_opt.h ap.h c_attach.o: c_attach.cc e_cardlist.h md.h io_trace.h io_error.h \ c_comand.h e_card.h e_base.h globals.h l_dispatcher.h l_stlextra.h \ u_opt.h mode.h io_.h l_lib.h ap.h c_file.o: c_file.cc u_lang.h u_opt.h mode.h io_.h l_lib.h md.h io_trace.h \ io_error.h c_comand.h e_card.h e_base.h globals.h l_dispatcher.h \ l_stlextra.h ap.h c_genrat.o: c_genrat.cc u_sim_data.h constant.h md.h io_trace.h \ io_error.h l_compar.h u_opt.h mode.h io_.h l_lib.h m_matrix.h \ l_stlextra.h globals.h l_dispatcher.h ap.h c_comand.h e_card.h e_base.h findbr.o: findbr.cc l_lib.h md.h io_trace.h io_error.h constant.h \ e_cardlist.h ap.h e_card.h e_base.h plot.o: plot.cc declare.h md.h io_trace.h io_error.h constant.h u_opt.h \ mode.h io_.h l_lib.h u_prblst.h u_probe.h l_compar.h main.o: main.cc e_cardlist.h md.h io_trace.h io_error.h u_lang.h u_opt.h \ mode.h io_.h l_lib.h ap.h patchlev.h c_comand.h e_card.h e_base.h \ declare.h globals.o: globals.cc globals.h l_dispatcher.h l_stlextra.h md.h \ io_trace.h io_error.h u_opt.h mode.h io_.h l_lib.h ap.h u_prblst.h \ u_probe.h l_compar.h e_cardlist.h u_status.h l_timer.h src/Make1000066400000000000000000000147541145401216200125350ustar00rootroot00000000000000#$Id: Make1,v 26.135 2009/12/02 09:26:53 al Exp $ -*- Makefile -*- # Copyright (C) 2001 Albert Davis # Author: Albert Davis # # This file is part of "Gnucap", the Gnu Circuit Analysis Package # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. #------------------------------------------------------------------------ TARGET = gnucap #------------------------------------------------------------------------ DELETED = \ s__.cc s__aux.cc s__map.cc #------------------------------------------------------------------------ # These source files can be omitted, and supplied as plugins. # device models defined in high level .model files MODELS = \ d_mos1.model d_mos2.model d_mos3.model \ d_mos4.model d_mos5.model d_mos6.model d_mos7.model d_mos8.model \ d_mos123.model d_mos_base.model d_mos.model \ d_bjt.model d_diode.model # device models hand coded in C++ D_SRCS = \ d_admit.cc d_cap.cc d_cccs.cc d_ccvs.cc d_coil.cc \ d_cs.cc d_poly_g.cc d_poly_cap.cc d_res.cc d_switch.cc \ d_trln.cc d_vcg.cc d_vcr.cc d_vcvs.cc d_vs.cc # behavioral modeling functions BM_SRCS = \ bm_complex.cc bm_cond.cc bm_exp.cc bm_fit.cc bm_generator.cc \ bm_model.cc bm_poly.cc bm_posy.cc bm_pulse.cc bm_pwl.cc bm_sffm.cc \ bm_sin.cc bm_tanh.cc bmm_table.cc bmm_semi.cc # utility commands, usually one file per command # some have multiple commands in a file C_SRCS = \ c_clear.cc c_comand.cc c_delete.cc c_exp.cc c_list.cc \ c_measure.cc c_modify.cc c_param.cc c_prbcmd.cc c_status.cc \ c_sweep.cc c_sim.cc c_system.cc # simulation commands, usually multiple files for one command S_SRCS = \ s_ac.cc s_dc.cc s_fo.cc \ s_tr.cc s_tr_set.cc s_tr_swp.cc # netlist languages LANG_SRCS = \ lang_spice.cc lang_spectre.cc lang_verilog.cc # parameter functions FUNC_SRCS = \ func_core.cc measure_eval.cc \ measure_max.cc measure_min.cc measure_slewrate.cc measure_cross.cc \ measure_integral.cc measure_average.cc measure_rms.cc measure_at.cc #------------------------------------------------------------------------ RAW_SRCS = \ $(D_SRCS) \ $(BM_SRCS) \ $(C_SRCS) \ $(S_SRCS) \ $(LANG_SRCS) \ $(FUNC_SRCS) \ m_expression_dump.cc m_expression_in.cc m_expression_reduce.cc \ m_base_in.cc m_base_math.cc m_fft.cc m_spline.cc \ ap_construct.cc ap_convert.cc ap_error.cc ap_get.cc ap_match.cc ap_skip.cc \ l_ftos.cc l_pmatch.cc l_timer.cc l_trim.cc l_wmatch.cc \ io.cc io_contr.cc io_error.cc io_findf.cc io_out.cc io_xopen.cc \ u_function.cc u_lang.cc u_nodemap.cc u_opt1.cc u_opt2.cc u_parameter.cc \ u_prblst.cc u_probe.cc u_sim_data.cc u_xprobe.cc \ s__init.cc s__out.cc s__solve.cc \ d_subckt.cc d_logic.cc d_logicmod.cc \ e_base.cc e_card.cc e_node.cc e_model.cc e_compon.cc \ e_elemnt.cc e_ccsrc.cc e_storag.cc e_cardlist.cc \ bm_value.cc bm.cc \ c__cmd.cc c_attach.cc c_file.cc c_genrat.cc \ findbr.cc plot.cc main.cc globals.cc #------------------------------------------------------------------------ RAW_HDRS = \ md.h ap.h mode.h constant.h declare.h patchlev.h \ l_compar.h l_dispatcher.h l_denoise.h \ l_lib.h l_stlextra.h l_timer.h \ m_cpoly.h m_divdiff.h m_interp.h m_matrix.h m_spline.h m_wave.h \ m_base.h m_expression.h m_phase.h \ io_.h io_error.h io_trace.h \ u_cardst.h u_function.h u_lang.h u_limit.h u_nodemap.h u_opt.h u_parameter.h \ u_prblst.h u_probe.h u_sim_data.h u_sdp.h u_status.h u_time_pair.h u_xprobe.h \ s__.h s_tr.h \ e_base.h e_card.h e_node.h e_aux.h e_model.h e_compon.h e_subckt.h \ e_elemnt.h e_ccsrc.h e_storag.h e_cardlist.h \ d_coment.h d_dot.h d_logic.h d_subckt.h \ bm.h \ c_comand.h globals.h #------------------------------------------------------------------------ RAW_OTHER = \ configure.old Make1 test_readline.cc spice-wrapper.cc \ Make3 Makefile.template \ Make2.g++ Make2.Debug Make2.mingw32 \ Makefile.am #------------------------------------------------------------------------ RAW = $(RAW_HDRS) $(RAW_SRCS) $(MODELS) $(RAW_OTHER) #------------------------------------------------------------------------ #------------------------------------------------------------------------ IMPORTED_SRCS = IMPORTED_HDRS = IMPORTED_OTHER = Makefile.in IMPORTED = $(IMPORTED_SRCS) $(IMPORTED_HDRS) $(IMPORTED_OTHER) #------------------------------------------------------------------------ #------------------------------------------------------------------------ GENERATED_SRCS = ${MODELS:.model=.cc} GENERATED_HDRS = ${MODELS:.model=.h} GENERATED_OTHER = Make.aux GENERATED = $(GENERATED_HDRS) $(GENERATED_SRCS) $(GENERATED_OTHER) #------------------------------------------------------------------------ #------------------------------------------------------------------------ GENERATED_DIST = Make.depend IMPORTED_DIST = $(IMPORTED) DISTFILES = $(RAW) $(GENERATED_DIST) $(IMPORTED_DIST) #------------------------------------------------------------------------ #------------------------------------------------------------------------ SRCS = $(IMPORTED_SRCS) $(GENERATED_SRCS) $(RAW_SRCS) HDRS = $(RAW_HDRS) $(GENERATED_HDRS) $(IMPORTED_HDRS) OBJS = ${SRCS:.cc=.o} TARGET_DEPENDS = $(OBJS) $(RAW) $(MODELS) #------------------------------------------------------------------------ #------------------------------------------------------------------------ MOSTLYCLEANFILES = $(OBJS) $(GENERATED) CLEANFILES = $(MOSTLYCLEANFILES) DISTCLEANFILES = $(CLEANFILES) MAINTAINERCLEANFILES = $(DISTCLEANFILES) #------------------------------------------------------------------------ #------------------------------------------------------------------------ all: $(TARGET) #------------------------------------------------------------------------ #------------------------------------------------------------------------ %.h : %.model gnucap-modelgen ./gnucap-modelgen -h $< #------------------------------------------------------------------------ %.cc : %.model gnucap-modelgen ./gnucap-modelgen -cc $< #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- src/Make2.Debug000066400000000000000000000072221145401216200135530ustar00rootroot00000000000000#$Id: Make2.Debug,v 26.97 2008/10/11 03:13:53 al Exp $ -*- Makefile -*- # Copyright (C) 2001 Albert Davis # Author: Albert Davis # # This file is part of "Gnucap", the Gnu Circuit Analysis Package # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. #------------------------------------------------------------------------ VPATH = .:.. # Standard base for g++, debugging, a little optimization # Running the program will give a spew of line markers for debugging. CCC = g++ CCFLAGS = \ -DHAVE_LIBREADLINE \ -DUNIX -g -O0 -I. -I.. -DTRACE_UNTESTED \ -Wall -Wextra \ -Wswitch-enum -Wundef -Wpointer-arith -Woverloaded-virtual \ -Wcast-qual -Wcast-align -Wpacked -Wshadow -Wconversion \ -Winit-self -Wmissing-include-dirs -Winvalid-pch \ -Wvolatile-register-var -Wstack-protector \ -Wlogical-op -Wvla -Woverlength-strings -Wsign-conversion #last line not in 4.1 LIBS = \ -lreadline -ltermcap \ LDFLAGS = -rdynamic %.SUFFIXES: .SUFFIXES: .o .cc .cc.o:; $(CCC) $(CCFLAGS) -c $< #------------------------------------------------------------------------ $(TARGET): $(TARGET_DEPENDS) rm -f $@ $(CCC) $(CCFLAGS) $(OBJS) $(LIBS) $(LDFLAGS) -o $@ #------------------------------------------------------------ # warnings turned off, because they warn of nothing wrong # 4.3 #-Wswitch-default -- lack of default is correct with enum #-Wfloat-equal -- warns on NA, div by zero trap #-Wpadded -- a bool in a class is enough #-Wredundant-decls -- in both header and func is an error check #-Wmissing-declarations -- pascal style #-Wmissing-noreturn -- warns when always throws exception #-Wunreachable-code -- warns even if reachable .. compiler bug?? #-Waggregate-return -- warns even if passed by reference #-Wunsafe-loop-optimizations -- if can't unroll a loop #-Winline #-Wdisabled-optimization -- -O0 disables optimization, so it warns # 4.2 #-Wpadded -- a bool in a class is enough #-Winline #-Waggregate-return -- warns even if passed by reference #-Wfloat-equal -- warns on NA, div by zero trap #-Wredundant-decls -- in both header and func is an error check #-Wunsafe-loop-optimizations -- warns on any loop with variable count # warnings turned off, because of the public headers #-Wunreachable-code -- didn't use nonportable syntax to hide #-Wmissing-noreturn -- didn't use nonportable syntax to hide # warnings that should be on, but ... #-Wshadow -- lambda functions #------------------------------------------------------------ # If you are porting and using g++, you should use this file as a start, # for a "debug" version, with extra warnings and run-time tracing. # If you get errors or warnings, make a copy of it and modify that. # After it works, use the file "Make2.g++" as a start for # executable to use. # If the port is non-trivial, check with me first because someone else # may have already done it. # If it works without changes, send me a note so I can put it in the docs. # Please send the changes to aldavis@gnu.org #------------------------------------------------------------ #------------------------------------------------------------ src/Make2.g++000066400000000000000000000042261145401216200131020ustar00rootroot00000000000000#$Id: Make2.g++,v 26.134 2009/11/29 03:47:06 al Exp $ -*- Makefile -*- # Copyright (C) 2001 Albert Davis # Author: Albert Davis # # This file is part of "Gnucap", the Gnu Circuit Analysis Package # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. #------------------------------------------------------------------------ VPATH = .:.. # Standard base for g++. CCC = g++ CCFLAGS = \ -DHAVE_LIBREADLINE \ -DUNIX -O3 -DNDEBUG -I.. -I. -W LIBS = \ -lreadline -ltermcap \ LDFLAGS = -rdynamic .SUFFIXES: .SUFFIXES: .o .cc .cc.o:; $(CCC) $(CCFLAGS) -c $< #------------------------------------------------------------------------ $(TARGET): $(TARGET_DEPENDS) rm -f $@ $(CCC) $(CCFLAGS) $(OBJS) $(LIBS) $(LDFLAGS) -o $@ #------------------------------------------------------------ # If you are porting and using g++, you should use this file as a start, # for a "release" version, optimized with run-time tracing removed. # If you get errors or warnings, make a copy of it and modify that. # For the first cut, use "Make2.Debug" as the start for more tracing, # or "Make2.Trace" for an extreme amount of tracing. # After it works, use the file "Make2.g++" as a start for # executable to use. # If the port is non-trivial, check with me first because someone else # may have already done it. # If it works without changes, send me a note so I can put it in the docs. # Please send the changes to aldavis@gnu.org #------------------------------------------------------------ #------------------------------------------------------------ src/Make2.mingw32000066400000000000000000000046721145401216200140210ustar00rootroot00000000000000#$Id: Make2.mingw32,v 26.81 2008/05/27 05:34:00 al Exp $ -*- Makefile -*- # Copyright (C) 2001 Albert Davis # Author: Albert Davis # # This file is part of "Gnucap", the Gnu Circuit Analysis Package # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. #------------------------------------------------------------------------ VPATH = .:.. # Standard base for g++. CCC = i586-mingw32msvc-g++ DLLTOOL = i586-mingw32msvc-dlltool CCFLAGS = \ -O2 -DNDEBUG -I.. -I. LIBS = \ LDFLAGS = .SUFFIXES: .SUFFIXES: .o .cc .cc.o:; $(CCC) $(CCFLAGS) -c $< #------------------------------------------------------------------------ $(TARGET): $(TARGET).exe lib$(TARGET).a #------------------------------------------------------------------------ $(TARGET).exe: $(TARGET_DEPENDS) rm -f $@ $(CCC) $(CCFLAGS) $(OBJS) $(LIBS) $(LDFLAGS) -o $@ #------------------------------------------------------------------------ lib$(TARGET).a: $(TARGET_DEPENDS) $(TARGET).exe rm -f $@ $(DLLTOOL) -l $@ -D $(TARGET).exe $(OBJS) $(LIBS) #------------------------------------------------------------ # If you are porting and using g++, you should use this file as a start, # for a "release" version, optimized with run-time tracing removed. # If you get errors or warnings, make a copy of it and modify that. # For the first cut, use "Make2.Debug" as the start for more tracing, # or "Make2.Trace" for an extreme amount of tracing. # After it works, use the file "Make2.g++" as a start for # executable to use. # If the port is non-trivial, check with me first because someone else # may have already done it. # If it works without changes, send me a note so I can put it in the docs. # Please send the changes to aldavis@gnu.org #------------------------------------------------------------ #------------------------------------------------------------ src/Make3000066400000000000000000000060041145401216200125240ustar00rootroot00000000000000#$Id: Make3,v 26.133 2009/11/26 04:58:04 al Exp $ -*- Makefile -*- # Copyright (C) 2001 Albert Davis # Author: Albert Davis # # This file is part of "Gnucap", the Gnu Circuit Analysis Package # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. #------------------------------------------------------------------------ # Part 3 of a Makefile #------------------------------------------------------------------------ tags: $(HDRS) $(SRCS) etags --c++ $(HDRS) $(SRCS) #------------------------------------------------------------------------ checkin: date "+#define PATCHLEVEL \"%Y.%m.%d RCS `cat rcsversion`\"" \ >patchlev.h -ci -u`cat rcsversion` -m. -t/dev/null $(RAW) -ci -r`cat rcsversion` -m. -t/dev/null $(DELETED) $(GENERATED) touch patchlev.h #------------------------------------------------------------------------ checkout: co $(RAW) #------------------------------------------------------------------------ #unclean: # rm $(ALL) #------------------------------------------------------------------------ backup: -mkdir BACKUP cp $(RAW) BACKUP #------------------------------------------------------------------------ depend: Make.depend Make.depend: $(SRCS) $(HDRS) $(CCC) -MM $(CCFLAGS) $(SRCS) > Make.depend #----------------------------------------------------------------------------- date: date "+#define PATCHLEVEL \"%Y.%m.%d RCS `cat rcsversion` +\"" \ >patchlev.h #----------------------------------------------------------------------------- header-check: $(CCC) -o /dev/null $(RAW_HDRS) #----------------------------------------------------------------------------- manifest: MANIFEST MANIFEST: $(DISTFILES) echo $(DISTFILES) | sed 's/ /\n/g' >MANIFEST #----------------------------------------------------------------------------- md5sums: MD5SUMS MD5SUMS: $(DISTFILES) md5sum $(DISTFILES) | grep -v MD5SUMS >MD5SUMS #----------------------------------------------------------------------------- mostlyclean: rm -rf $(MOSTLYCLEANFILES) rm -f */*.o */*.obj */*.h */*.cc clean: rm -rf $(CLEANFILES) rm -f */*.o */*.obj */*.h */*.cc distclean: rm -rf $(DISTCLEANFILES) rm -f */*.o */*.obj */*.h */*.cc rm -f *~ \#*\# maintainer-clean: rm -rf $(MAINTAINERCLEANFILES) rm -f */*.o */*.obj */*.h */*.cc rm -f *~ \#*\# #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- src/Makefile.am000066400000000000000000000121171145401216200136770ustar00rootroot00000000000000## -*- Makefile -*- ## ## $Id: Makefile.am,v 26.136 2009/12/08 02:03:49 al Exp $ ## ## COPYRIGHT ## ## This file is part of "Gnucap", the Gnu Circuit Analysis Package ## ## Copyright (C) 2005, 2006 Dan McMahill ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ## 02110-1301, USA. bin_PROGRAMS= gnucap #------------------------------------------------------------------------ #------------------------------------------------------------------------ # These source files can be omitted, and supplied as plugins. # device models defined in high level .model files MODELS = \ d_mos1.model d_mos2.model d_mos3.model \ d_mos4.model d_mos5.model d_mos6.model d_mos7.model d_mos8.model \ d_mos123.model d_mos_base.model d_mos.model \ d_bjt.model d_diode.model # device models hand coded in C++ D_SRCS = \ d_admit.cc d_cap.cc d_cccs.cc d_ccvs.cc d_coil.cc \ d_cs.cc d_poly_g.cc d_poly_cap.cc d_res.cc d_switch.cc \ d_trln.cc d_vcg.cc d_vcr.cc d_vcvs.cc d_vs.cc # behavioral modeling functions BM_SRCS = \ bm_complex.cc bm_cond.cc bm_exp.cc bm_fit.cc bm_generator.cc \ bm_model.cc bm_poly.cc bm_posy.cc bm_pulse.cc bm_pwl.cc bm_sffm.cc \ bm_sin.cc bm_tanh.cc bmm_table.cc bmm_semi.cc # utility commands, usually one file per command # some have multiple commands in a file C_SRCS = \ c_clear.cc c_comand.cc c_delete.cc c_exp.cc c_list.cc \ c_measure.cc c_modify.cc c_param.cc c_prbcmd.cc c_status.cc \ c_sweep.cc c_sim.cc c_system.cc # simulation commands, usually multiple files for one command S_SRCS = \ s_ac.cc s_dc.cc s_fo.cc \ s_tr.cc s_tr_set.cc s_tr_swp.cc # netlist languages LANG_SRCS = \ lang_spice.cc lang_spectre.cc lang_verilog.cc # parameter functions FUNC_SRCS = \ func_core.cc measure_eval.cc \ measure_max.cc measure_min.cc measure_slewrate.cc measure_cross.cc \ measure_integral.cc measure_average.cc measure_rms.cc measure_at.cc #------------------------------------------------------------------------ RAW_SRCS = \ $(D_SRCS) \ $(BM_SRCS) \ $(C_SRCS) \ $(S_SRCS) \ $(LANG_SRCS) \ $(FUNC_SRCS) \ m_expression_dump.cc m_expression_in.cc m_expression_reduce.cc \ m_base_in.cc m_base_math.cc m_fft.cc m_spline.cc \ ap_construct.cc ap_convert.cc ap_error.cc ap_get.cc ap_match.cc ap_skip.cc \ l_ftos.cc l_pmatch.cc l_timer.cc l_trim.cc l_wmatch.cc \ io.cc io_contr.cc io_error.cc io_findf.cc io_out.cc io_xopen.cc \ u_function.cc u_lang.cc u_nodemap.cc u_opt1.cc u_opt2.cc u_parameter.cc \ u_prblst.cc u_probe.cc u_sim_data.cc u_xprobe.cc \ s__init.cc s__out.cc s__solve.cc \ d_subckt.cc d_logic.cc d_logicmod.cc \ e_base.cc e_card.cc e_node.cc e_model.cc e_compon.cc \ e_elemnt.cc e_ccsrc.cc e_storag.cc e_cardlist.cc \ bm_value.cc bm.cc \ c__cmd.cc c_attach.cc c_file.cc c_genrat.cc \ findbr.cc plot.cc main.cc globals.cc #------------------------------------------------------------------------ RAW_HDRS = \ md.h ap.h mode.h constant.h declare.h patchlev.h \ l_compar.h l_dispatcher.h l_denoise.h \ l_lib.h l_stlextra.h l_timer.h \ m_cpoly.h m_divdiff.h m_interp.h m_matrix.h m_spline.h m_wave.h \ m_base.h m_expression.h m_phase.h \ io_.h io_error.h io_trace.h \ u_cardst.h u_function.h u_lang.h u_limit.h u_nodemap.h u_opt.h u_parameter.h \ u_prblst.h u_probe.h u_sim_data.h u_sdp.h u_status.h u_time_pair.h u_xprobe.h \ s__.h s_tr.h \ e_base.h e_card.h e_node.h e_aux.h e_model.h e_compon.h e_subckt.h \ e_elemnt.h e_ccsrc.h e_storag.h e_cardlist.h \ d_coment.h d_dot.h d_logic.h d_subckt.h \ bm.h \ c_comand.h globals.h #------------------------------------------------------------------------ ## The modelgen generated files MODELSRCS= ${MODELS:.model=.cc} ${MODELS:.model=.h} MODELOBJS= ${MODELS:.model=.${OBJEXT}} nodist_gnucap_SOURCES= ${SRCS1} ${MODELSRCS} ${SRCS2} SRCS1= SRCS2= ${RAW_SRCS} ${RAW_HDRS} # make all of the model object files depend on all of the model sources # this is a bit overkill, but for example the bjt model makes use of the # diode model and we want to be sure and capture that dependency ${MODELOBJS}: ${MODELSRCS} ## Include the .model files in the distfile as well as the rest of the ## non-generated sources EXTRA_DIST= ${MODELS} ${SRCS1} ${SRCS2} \ configure.old Make1 test_readline.cc spice-wrapper.cc \ Make3 Makefile.template \ Make2.g++ Make2.Debug Make2.mingw32 \ Makefile.am ### Clean out the modelgen generated files CLEANFILES= ${MODELSRCS} ## Suffix rules for modelgen. ## SUFFIXES= .model MODELGEN= @MODELGEN@ %.cc : %.model %.h ${MODELGEN}${EXEEXT} ${MODELGEN} -cc $< %.h : %.model ${MODELGEN}${EXEEXT} ${MODELGEN} -h $< src/Makefile.in000066400000000000000000000742051145401216200137160ustar00rootroot00000000000000# Makefile.in generated by automake 1.11 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = gnucap$(EXEEXT) subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am__objects_1 = am__objects_2 = d_mos1.$(OBJEXT) d_mos2.$(OBJEXT) d_mos3.$(OBJEXT) \ d_mos4.$(OBJEXT) d_mos5.$(OBJEXT) d_mos6.$(OBJEXT) \ d_mos7.$(OBJEXT) d_mos8.$(OBJEXT) d_mos123.$(OBJEXT) \ d_mos_base.$(OBJEXT) d_mos.$(OBJEXT) d_bjt.$(OBJEXT) \ d_diode.$(OBJEXT) am__objects_3 = $(am__objects_2) $(am__objects_1) am__objects_4 = d_admit.$(OBJEXT) d_cap.$(OBJEXT) d_cccs.$(OBJEXT) \ d_ccvs.$(OBJEXT) d_coil.$(OBJEXT) d_cs.$(OBJEXT) \ d_poly_g.$(OBJEXT) d_poly_cap.$(OBJEXT) d_res.$(OBJEXT) \ d_switch.$(OBJEXT) d_trln.$(OBJEXT) d_vcg.$(OBJEXT) \ d_vcr.$(OBJEXT) d_vcvs.$(OBJEXT) d_vs.$(OBJEXT) am__objects_5 = bm_complex.$(OBJEXT) bm_cond.$(OBJEXT) \ bm_exp.$(OBJEXT) bm_fit.$(OBJEXT) bm_generator.$(OBJEXT) \ bm_model.$(OBJEXT) bm_poly.$(OBJEXT) bm_posy.$(OBJEXT) \ bm_pulse.$(OBJEXT) bm_pwl.$(OBJEXT) bm_sffm.$(OBJEXT) \ bm_sin.$(OBJEXT) bm_tanh.$(OBJEXT) bmm_table.$(OBJEXT) \ bmm_semi.$(OBJEXT) am__objects_6 = c_clear.$(OBJEXT) c_comand.$(OBJEXT) \ c_delete.$(OBJEXT) c_exp.$(OBJEXT) c_list.$(OBJEXT) \ c_measure.$(OBJEXT) c_modify.$(OBJEXT) c_param.$(OBJEXT) \ c_prbcmd.$(OBJEXT) c_status.$(OBJEXT) c_sweep.$(OBJEXT) \ c_sim.$(OBJEXT) c_system.$(OBJEXT) am__objects_7 = s_ac.$(OBJEXT) s_dc.$(OBJEXT) s_fo.$(OBJEXT) \ s_tr.$(OBJEXT) s_tr_set.$(OBJEXT) s_tr_swp.$(OBJEXT) am__objects_8 = lang_spice.$(OBJEXT) lang_spectre.$(OBJEXT) \ lang_verilog.$(OBJEXT) am__objects_9 = func_core.$(OBJEXT) measure_eval.$(OBJEXT) \ measure_max.$(OBJEXT) measure_min.$(OBJEXT) \ measure_slewrate.$(OBJEXT) measure_cross.$(OBJEXT) \ measure_integral.$(OBJEXT) measure_average.$(OBJEXT) \ measure_rms.$(OBJEXT) measure_at.$(OBJEXT) am__objects_10 = $(am__objects_4) $(am__objects_5) $(am__objects_6) \ $(am__objects_7) $(am__objects_8) $(am__objects_9) \ m_expression_dump.$(OBJEXT) m_expression_in.$(OBJEXT) \ m_expression_reduce.$(OBJEXT) m_base_in.$(OBJEXT) \ m_base_math.$(OBJEXT) m_fft.$(OBJEXT) m_spline.$(OBJEXT) \ ap_construct.$(OBJEXT) ap_convert.$(OBJEXT) ap_error.$(OBJEXT) \ ap_get.$(OBJEXT) ap_match.$(OBJEXT) ap_skip.$(OBJEXT) \ l_ftos.$(OBJEXT) l_pmatch.$(OBJEXT) l_timer.$(OBJEXT) \ l_trim.$(OBJEXT) l_wmatch.$(OBJEXT) io.$(OBJEXT) \ io_contr.$(OBJEXT) io_error.$(OBJEXT) io_findf.$(OBJEXT) \ io_out.$(OBJEXT) io_xopen.$(OBJEXT) u_function.$(OBJEXT) \ u_lang.$(OBJEXT) u_nodemap.$(OBJEXT) u_opt1.$(OBJEXT) \ u_opt2.$(OBJEXT) u_parameter.$(OBJEXT) u_prblst.$(OBJEXT) \ u_probe.$(OBJEXT) u_sim_data.$(OBJEXT) u_xprobe.$(OBJEXT) \ s__init.$(OBJEXT) s__out.$(OBJEXT) s__solve.$(OBJEXT) \ d_subckt.$(OBJEXT) d_logic.$(OBJEXT) d_logicmod.$(OBJEXT) \ e_base.$(OBJEXT) e_card.$(OBJEXT) e_node.$(OBJEXT) \ e_model.$(OBJEXT) e_compon.$(OBJEXT) e_elemnt.$(OBJEXT) \ e_ccsrc.$(OBJEXT) e_storag.$(OBJEXT) e_cardlist.$(OBJEXT) \ bm_value.$(OBJEXT) bm.$(OBJEXT) c__cmd.$(OBJEXT) \ c_attach.$(OBJEXT) c_file.$(OBJEXT) c_genrat.$(OBJEXT) \ findbr.$(OBJEXT) plot.$(OBJEXT) main.$(OBJEXT) \ globals.$(OBJEXT) am__objects_11 = $(am__objects_10) $(am__objects_1) nodist_gnucap_OBJECTS = $(am__objects_1) $(am__objects_3) \ $(am__objects_11) gnucap_OBJECTS = $(nodist_gnucap_OBJECTS) gnucap_LDADD = $(LDADD) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(nodist_gnucap_SOURCES) DIST_SOURCES = ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EXEEXT = @EXEEXT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MODELGEN = @MODELGEN@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ #------------------------------------------------------------------------ #------------------------------------------------------------------------ # These source files can be omitted, and supplied as plugins. # device models defined in high level .model files MODELS = \ d_mos1.model d_mos2.model d_mos3.model \ d_mos4.model d_mos5.model d_mos6.model d_mos7.model d_mos8.model \ d_mos123.model d_mos_base.model d_mos.model \ d_bjt.model d_diode.model # device models hand coded in C++ D_SRCS = \ d_admit.cc d_cap.cc d_cccs.cc d_ccvs.cc d_coil.cc \ d_cs.cc d_poly_g.cc d_poly_cap.cc d_res.cc d_switch.cc \ d_trln.cc d_vcg.cc d_vcr.cc d_vcvs.cc d_vs.cc # behavioral modeling functions BM_SRCS = \ bm_complex.cc bm_cond.cc bm_exp.cc bm_fit.cc bm_generator.cc \ bm_model.cc bm_poly.cc bm_posy.cc bm_pulse.cc bm_pwl.cc bm_sffm.cc \ bm_sin.cc bm_tanh.cc bmm_table.cc bmm_semi.cc # utility commands, usually one file per command # some have multiple commands in a file C_SRCS = \ c_clear.cc c_comand.cc c_delete.cc c_exp.cc c_list.cc \ c_measure.cc c_modify.cc c_param.cc c_prbcmd.cc c_status.cc \ c_sweep.cc c_sim.cc c_system.cc # simulation commands, usually multiple files for one command S_SRCS = \ s_ac.cc s_dc.cc s_fo.cc \ s_tr.cc s_tr_set.cc s_tr_swp.cc # netlist languages LANG_SRCS = \ lang_spice.cc lang_spectre.cc lang_verilog.cc # parameter functions FUNC_SRCS = \ func_core.cc measure_eval.cc \ measure_max.cc measure_min.cc measure_slewrate.cc measure_cross.cc \ measure_integral.cc measure_average.cc measure_rms.cc measure_at.cc #------------------------------------------------------------------------ RAW_SRCS = \ $(D_SRCS) \ $(BM_SRCS) \ $(C_SRCS) \ $(S_SRCS) \ $(LANG_SRCS) \ $(FUNC_SRCS) \ m_expression_dump.cc m_expression_in.cc m_expression_reduce.cc \ m_base_in.cc m_base_math.cc m_fft.cc m_spline.cc \ ap_construct.cc ap_convert.cc ap_error.cc ap_get.cc ap_match.cc ap_skip.cc \ l_ftos.cc l_pmatch.cc l_timer.cc l_trim.cc l_wmatch.cc \ io.cc io_contr.cc io_error.cc io_findf.cc io_out.cc io_xopen.cc \ u_function.cc u_lang.cc u_nodemap.cc u_opt1.cc u_opt2.cc u_parameter.cc \ u_prblst.cc u_probe.cc u_sim_data.cc u_xprobe.cc \ s__init.cc s__out.cc s__solve.cc \ d_subckt.cc d_logic.cc d_logicmod.cc \ e_base.cc e_card.cc e_node.cc e_model.cc e_compon.cc \ e_elemnt.cc e_ccsrc.cc e_storag.cc e_cardlist.cc \ bm_value.cc bm.cc \ c__cmd.cc c_attach.cc c_file.cc c_genrat.cc \ findbr.cc plot.cc main.cc globals.cc #------------------------------------------------------------------------ RAW_HDRS = \ md.h ap.h mode.h constant.h declare.h patchlev.h \ l_compar.h l_dispatcher.h l_denoise.h \ l_lib.h l_stlextra.h l_timer.h \ m_cpoly.h m_divdiff.h m_interp.h m_matrix.h m_spline.h m_wave.h \ m_base.h m_expression.h m_phase.h \ io_.h io_error.h io_trace.h \ u_cardst.h u_function.h u_lang.h u_limit.h u_nodemap.h u_opt.h u_parameter.h \ u_prblst.h u_probe.h u_sim_data.h u_sdp.h u_status.h u_time_pair.h u_xprobe.h \ s__.h s_tr.h \ e_base.h e_card.h e_node.h e_aux.h e_model.h e_compon.h e_subckt.h \ e_elemnt.h e_ccsrc.h e_storag.h e_cardlist.h \ d_coment.h d_dot.h d_logic.h d_subckt.h \ bm.h \ c_comand.h globals.h #------------------------------------------------------------------------ MODELSRCS = ${MODELS:.model=.cc} ${MODELS:.model=.h} MODELOBJS = ${MODELS:.model=.${OBJEXT}} nodist_gnucap_SOURCES = ${SRCS1} ${MODELSRCS} ${SRCS2} SRCS1 = SRCS2 = ${RAW_SRCS} ${RAW_HDRS} EXTRA_DIST = ${MODELS} ${SRCS1} ${SRCS2} \ configure.old Make1 test_readline.cc spice-wrapper.cc \ Make3 Makefile.template \ Make2.g++ Make2.Debug Make2.mingw32 \ Makefile.am ### Clean out the modelgen generated files CLEANFILES = ${MODELSRCS} SUFFIXES = .model all: all-am .SUFFIXES: .SUFFIXES: .model .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) gnucap$(EXEEXT): $(gnucap_OBJECTS) $(gnucap_DEPENDENCIES) @rm -f gnucap$(EXEEXT) $(CXXLINK) $(gnucap_OBJECTS) $(gnucap_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ap_construct.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ap_convert.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ap_error.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ap_get.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ap_match.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ap_skip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bm_complex.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bm_cond.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bm_exp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bm_fit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bm_generator.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bm_model.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bm_poly.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bm_posy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bm_pulse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bm_pwl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bm_sffm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bm_sin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bm_tanh.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bm_value.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmm_semi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmm_table.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c__cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_attach.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_clear.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_comand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_delete.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_exp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_genrat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_measure.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_modify.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_param.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_prbcmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_sim.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_status.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_sweep.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_system.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_admit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_bjt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_cap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_cccs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_ccvs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_coil.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_cs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_diode.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_logic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_logicmod.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_mos.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_mos1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_mos123.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_mos2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_mos3.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_mos4.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_mos5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_mos6.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_mos7.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_mos8.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_mos_base.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_poly_cap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_poly_g.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_res.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_subckt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_switch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_trln.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_vcg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_vcr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_vcvs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_vs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_base.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_card.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_cardlist.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_ccsrc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_compon.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_elemnt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_model.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_node.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_storag.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findbr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/func_core.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/globals.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io_contr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io_error.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io_findf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io_out.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io_xopen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/l_ftos.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/l_pmatch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/l_timer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/l_trim.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/l_wmatch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lang_spectre.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lang_spice.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lang_verilog.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_base_in.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_base_math.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_expression_dump.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_expression_in.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_expression_reduce.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_fft.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_spline.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/measure_at.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/measure_average.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/measure_cross.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/measure_eval.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/measure_integral.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/measure_max.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/measure_min.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/measure_rms.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/measure_slewrate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plot.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s__init.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s__out.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s__solve.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_ac.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_dc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_fo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_tr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_tr_set.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_tr_swp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_function.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_lang.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_nodemap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_opt1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_opt2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_parameter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_prblst.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_probe.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_sim_data.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_xprobe.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-binPROGRAMS # make all of the model object files depend on all of the model sources # this is a bit overkill, but for example the bjt model makes use of the # diode model and we want to be sure and capture that dependency ${MODELOBJS}: ${MODELSRCS} %.cc : %.model %.h ${MODELGEN}${EXEEXT} ${MODELGEN} -cc $< %.h : %.model ${MODELGEN}${EXEEXT} ${MODELGEN} -h $< # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: src/Makefile.template000066400000000000000000000117251145401216200151210ustar00rootroot00000000000000#$Id: Makefile.template,v 26.133 2009/11/26 04:58:04 al Exp $ -*- Makefile -*- # Copyright (C) 2001 Albert Davis # Author: Albert Davis # # This file is part of "Gnucap", the Gnu Circuit Analysis Package # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. #------------------------------------------------------------------------ # In most cases you can just type "make" to build it. # Generally, you will want "make your-system". # Look in this file for the choices. # If yours is not here, look for a similar one and copy. # The special configurations listed here allow you to do multiple builds # from the same source directory, and patch some problems. #----------------------------------------------------------------------------- # The default is to use the makefile built by "configure" default: nothing -mkdir O cat Make1 Make2 Make3 Make.depend >O/Makefile (cd O; ${MAKE} -k) #----------------------------------------------------------------------------- # The most common configuration is g++ # This should work if it is properly installed # and has the proper libraries and headers. # It is optimized for speed. Debugging is off. g++: nothing -mkdir O cat Make1 Make2.g++ Make3 Make.depend >O/Makefile (cd O; ${MAKE} -k) #----------------------------------------------------------------------------- # This one makes a "debug" build ... # Asserts and some tracing is turned on. # It prints a trace when "untested" code is exercised. # "Untested" means the regressions don't test it. # It doesn't mean TOTALLY untested. debug: nothing -mkdir O-DEBUG cat Make1 Make2.Debug Make3 Make.depend >O-DEBUG/Makefile (cd O-DEBUG; ${MAKE} -k) #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # MS Windows using mingw32 mingw: nothing -mkdir MSW cat Make1 Make2.mingw32 Make3 Make.depend >MSW/Makefile (cd MSW; ${MAKE} -k) #----------------------------------------------------------------------------- tags: nothing cat Make1 Make2.g++ Make3 >Make.aux (${MAKE} tags -f Make.aux) #----------------------------------------------------------------------------- depend: nothing cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux depend #----------------------------------------------------------------------------- checkin: nothing cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux checkin #----------------------------------------------------------------------------- checkout: nothing cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux checkout #----------------------------------------------------------------------------- # Note that the /usr/local directory is overwritten by configure. install: nothing if test -d /usr/local/bin; then \ cp O/gnucap /usr/local/bin/gnucap; \ else \ mkdir -p /usr/local/bin && \ cp O/gnucap /usr/local/bin/gnucap; \ fi #----------------------------------------------------------------------------- uninstall: clean -rm /usr/local/bin/gnucap #----------------------------------------------------------------------------- unconfig: rm -f Makefile #----------------------------------------------------------------------------- date: nothing cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux date #----------------------------------------------------------------------------- header-check: cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux header-check #----------------------------------------------------------------------------- manifest: cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux manifest #----------------------------------------------------------------------------- md5sums: cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux md5sums #----------------------------------------------------------------------------- mostlyclean: cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux mostlyclean clean: cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux clean distclean: cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux distclean maintainer-clean: cat Make1 Make2.g++ Make3 >Make.aux ${MAKE} -f Make.aux maintainer-clean #----------------------------------------------------------------------------- nothing: #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- src/ap.h000066400000000000000000000173101145401216200124140ustar00rootroot00000000000000/*$Id: ap.h,v 26.130 2009/11/15 21:51:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * stuff for the "ap" family of parsing functions */ //testing=script,sparse 2006.07.17 #ifndef AP_H #define AP_H #include "md.h" /*--------------------------------------------------------------------------*/ char* getcmd(const char*,char*,int); /*--------------------------------------------------------------------------*/ enum AP_MOD{ mNONE, /* nothing special */ mSCALE, /* scale it after reading */ mOFFSET, /* add an offset */ mINVERT, /* save 1 / the number */ mPOSITIVE, /* store absolute value */ mOCTAL, /* read the number in octal */ mHEX /* read the number in hex */ }; const bool ONE_OF = false; class INTERFACE CS { public: enum STDIN {_STDIN}; enum INC_FILE {_INC_FILE}; enum WHOLE_FILE {_WHOLE_FILE}; enum STRING {_STRING}; private: FILE* _file; std::string _name; std::string _cmd; unsigned _cnt; unsigned _length; unsigned _begin_match; unsigned _end_match; bool _ok; int _line_number; public: // construction, destruction, and re-construction explicit CS(STDIN); explicit CS(INC_FILE, const std::string& name); explicit CS(WHOLE_FILE, const std::string& name); explicit CS(STRING, const std::string& s); explicit CS(const CS& p); CS& operator=(const std::string& s); CS& operator=(const CS& p); CS& get_line(const std::string& prompt); ~CS() {if (is_file()) {fclose(_file);}} // status - non-consuming unsigned cursor()const {return _cnt;} bool stuck(unsigned* last) {bool ok=*last<_cnt; *last=_cnt; return !ok;} bool gotit(unsigned last) {return last<_cnt;} operator bool()const {return _ok;} // get -- non-consuming const std::string fullstring()const {return _cmd;} const std::string substr(unsigned i)const {return ((_cmd.length()>=i) ? _cmd.substr(i) : "");} const std::string substr(unsigned i, unsigned n)const {return _cmd.substr(i,n);} const std::string tail()const {return substr(_cnt);} char peek()const {return _cmd[_cnt];} // status - may consume whitespace only bool ns_more()const {return peek()!='\0';} bool more() {skipbl(); return ns_more();} bool is_end() {return !more();} bool is_file() {return (_file && !isatty(fileno(_file)));} bool is_first_read()const {untested(); return (_line_number == 0);} // control CS& reset(unsigned c=0) {_cnt=c; _ok=true; return *this;} // exception handling (ap_error.cc) non-consuming CS& check(int, const std::string&); CS& warn(int, unsigned, const std::string&); CS& warn(int i, const std::string& s) {return warn(i,cursor(), s);} // string matching (ap_match.cc) possibly consuming, sets _ok CS& umatch(const std::string&); CS& scan(const std::string&); std::string last_match()const; std::string trimmed_last_match(const std::string& = " ,=;")const; // character tests - non-consuming, no _ok bool match1(char c)const{return (peek()==c);} bool match1(const std::string& c)const {return ns_more() && strchr(c.c_str(),peek());} size_t find1(const std::string& c)const {return ((ns_more()) ? c.find_first_of(peek()) : std::string::npos);} bool is_xdigit()const {untested(); return (match1("0123456789abcdefABCDEF"));} bool is_digit()const {return (match1("0123456789"));} bool is_pfloat()const {return (match1(".0123456789"));} bool is_float()const {return (match1("+-.0123456789"));} bool is_argsym()const {return (match1("*?$%_&@"));} bool is_alpha()const {return !!isalpha(toascii(peek()));} bool is_alnum()const {return !!isalnum(toascii(peek()));} bool is_term(const std::string& t = ",=(){};") {char c=peek(); return (c=='\0' || isspace(c) || match1(t));} // conversions (ap_convert.cc) always consuming char ctoc(); void ctostr(char*,int,const std::string&); std::string ctos(const std::string& term=",=(){};", const std::string& b="\"'{", const std::string& e="\"'}", const std::string& trap=""); std::string get_to(const std::string& term); // conversions (ap_convert.cc) consumes if successful, sets _ok double ctof(); bool ctob(); int ctoi(); unsigned ctou(); int ctoo(); int ctox(); double ctopf() {return std::abs(ctof());} CS& operator>>(bool& x) {x=ctob();return *this;} CS& operator>>(char& x) {untested(); x=ctoc();return *this;} CS& operator>>(int& x) {x=ctoi();return *this;} CS& operator>>(unsigned& x) {x=ctou();return *this;} CS& operator>>(double& x) {x=ctof();return *this;} CS& operator>>(std::string& x) {x=ctos();return *this;} // skip (ap_skip.cc) possibly consuming, sets _ok CS& skip(int c=1) {_cnt=static_cast(static_cast(_cnt)+c); _ok=_cnt<=_length; return *this;} CS& skipbl(); CS& skip1b(char); CS& skip1(char); CS& skip1b(const std::string&); CS& skip1(const std::string&); CS& skiparg(); CS& skipto1(const std::string&); CS& skipto1(char); CS& skipcom() {return skip1b(",");} CS& operator>>(const char& x) {return skip1b(x);} CS& operator>>(const char* x) {return umatch(x);} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ // these are non-member to provide a consistent interface, // like the templates to follow INTERFACE bool Get(CS& cmd, const std::string&, bool*); INTERFACE bool Get(CS& cmd, const std::string&, int*, AP_MOD=mNONE, int=0); INTERFACE bool Get(CS& cmd, const std::string&, double*, AP_MOD, double=0.); /*--------------------------------------------------------------------------*/ template bool Get(CS& cmd, const std::string& key, T* val) { if (cmd.umatch(key + " {=}")) { cmd >> *val; return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ template inline bool scan_get(CS& cmd, const std::string& key, T* val) { if (cmd.scan(key)) { cmd >> '=' >> *val; return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ template inline bool Set(CS& cmd, const std::string& key, T* val, T newval) { if (cmd.umatch(key + ' ')) { *val = newval; return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ template inline CS& operator>>(CS& cmd, T& val) { val.parse(cmd); return cmd; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif src/ap_construct.cc000066400000000000000000000157351145401216200146670ustar00rootroot00000000000000/*$Id: ap_construct.cc,v 26.130 2009/11/15 21:51:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * construction, copy, etc. */ //testing=script,sparse 2006.07.17 #include "u_opt.h" #include "ap.h" #if defined(HAVE_LIBREADLINE) #include #include #endif /*--------------------------------------------------------------------------*/ static std::string getlines(FILE*); OMSTREAM mout; // > file bitmap //BUG//encapsulation OMSTREAM mlog; // log file bitmap /*--------------------------------------------------------------------------*/ CS::CS(CS::STDIN) :_file(stdin), _name(), _cmd(), _cnt(0), _length(0), _begin_match(0), _end_match(0), _ok(true), _line_number(0) { } /*--------------------------------------------------------------------------*/ CS::CS(CS::INC_FILE, const std::string& name) :_file(fopen(name.c_str(), "r")), _name(name), _cmd(), _cnt(0), _length(0), _begin_match(0), _end_match(0), _ok(true), _line_number(0) { if (!_file) {itested(); throw Exception_File_Open(name + ':' + strerror(errno)); }else{ } } /*--------------------------------------------------------------------------*/ CS::CS(CS::WHOLE_FILE, const std::string& name) :_file(NULL), _name(name), _cmd(), _cnt(0), _length(0), _begin_match(0), _end_match(0), _ok(true), _line_number(0) { int f = open(name.c_str(), O_RDONLY); if (f == EOF) {itested(); throw Exception_File_Open(name + ':' + strerror(errno)); }else{ } _length = static_cast(lseek(f, off_t(0), SEEK_END)); lseek(f, off_t(0), SEEK_SET); char* cmd = new char[_length+2]; read(f, cmd, _length); cmd[_length++] = '\0'; _cmd = cmd; close(f); } /*--------------------------------------------------------------------------*/ CS::CS(CS::STRING, const std::string& s) :_file(NULL), _name(), _cmd(s), _cnt(0), _length(static_cast(s.length())), _begin_match(0), _end_match(0), _ok(true), _line_number(0) { } /*--------------------------------------------------------------------------*/ #if 0 CS::CS(const CS& p) :_file(NULL), _name(p._name), _cmd(p._cmd), _cnt(p._cnt), _length(p._length), _begin_match(0), _end_match(0), _ms(p._ms), _ok(p._ok), _line_number(0) {untested(); } #endif /*--------------------------------------------------------------------------*/ CS& CS::operator=(const std::string& s) {untested(); assert(!_file); _cmd = s; _cnt = 0; _ok = true; _length = static_cast(s.length()); return *this; } /*--------------------------------------------------------------------------*/ #if 0 CS& CS::operator=(const CS& p) {untested(); assert(&p != this); _name = p._name; _file = p._file; _cmd = p._cmd; _cnt = p._cnt; _ok = p._ok; _length = p._length; return *this; } #endif /*--------------------------------------------------------------------------*/ CS& CS::get_line(const std::string& prompt) { ++_line_number; if (is_file()) { _cmd = getlines(_file); _cnt = 0; _length = static_cast(_cmd.length()); _ok = true; }else{itested(); assert(_file == stdin); char cmdbuf[BUFLEN]; getcmd(prompt.c_str(), cmdbuf, BUFLEN); _cmd = cmdbuf; _cnt = 0; _length = static_cast(_cmd.length()); _ok = true; } if (OPT::listing) { IO::mstdout << "\"" << fullstring() << "\"\n"; }else{ } return *this; } /*--------------------------------------------------------------------------*/ /* getcmd: get a command. * if "fin" is stdin, display a prompt first. * Also, actually do logging, echo, etc. */ char *getcmd(const char *prompt, char *buffer, int buflen) { assert(prompt); assert(buffer); if (isatty(fileno(stdin))) { // stdin is keyboard #if defined(HAVE_LIBREADLINE) if (OPT::edit) { char* line_read = readline(prompt); if (!line_read) {itested(); throw Exception_End_Of_Input("EOF on stdin"); }else{ } // readline gets a new buffer every time, so copy it to where we want it char* end_of_line = (char*)memccpy(buffer, line_read, 0, static_cast(buflen-1)); if (!end_of_line) { buffer[buflen-1] = '\0'; }else{ *end_of_line = '\0'; } free(line_read); if (*buffer) { add_history(buffer); }else{ } }else #endif { IO::mstdout << prompt; /* prompt & flush buffer */ if (!fgets(buffer, buflen, stdin)) {untested(); /* read line */ throw Exception_End_Of_Input("EOF on stdin"); }else{ } } (IO::mstdout - mout) << '\r'; /* reset col counter */ trim(buffer); (mlog + mout) << buffer << '\n'; return buffer; }else{ // stdin is file if (!fgets(buffer, buflen, stdin)) {itested(); /* read line */ throw Exception_End_Of_Input("EOF on stdin"); }else{ } trim(buffer); (mlog + mout) << buffer << '\n'; return buffer; } } /*--------------------------------------------------------------------------*/ static std::string getlines(FILE *fileptr) { assert(fileptr); const int buffer_size = BIGBUFLEN; std::string s; bool need_to_get_more = true; // get another line (extend) while (need_to_get_more) { char buffer[buffer_size+1]; char* got_something = fgets(buffer, buffer_size, fileptr); if (!got_something) { // probably end of file need_to_get_more = false; if (s == "") { throw Exception_End_Of_Input(""); }else{untested(); } }else{ trim(buffer); size_t count = strlen(buffer); if (buffer[count-1] == '\\') {itested(); buffer[count-1] = '\0'; }else{ // look ahead at next line //int c = fgetc(fileptr); int c; while (isspace(c = fgetc(fileptr))) { // skip } if (c == '+') { need_to_get_more = true; }else if (c == '\n') {unreachable(); need_to_get_more = true; ungetc(c,fileptr); }else{ need_to_get_more = false; ungetc(c,fileptr); } } s += buffer; s += ' '; } } return s; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/ap_convert.cc000066400000000000000000000217731145401216200143220ustar00rootroot00000000000000/*$Id: ap_convert.cc,v 26.125 2009/10/15 20:58:21 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script 2006.07.17 #include "u_opt.h" #include "ap.h" /*--------------------------------------------------------------------------*/ // char CS::ctoc(); // void CS::ctostr(char* d, int l, const string& t); // string CS::ctos(const string& term); // int CS::ctoi(); // unsigned CS::ctou(); // int CS::ctoo(); // int CS::ctox(); // double CS::ctof(); /*--------------------------------------------------------------------------*/ /* ctoc: character input to character */ char CS::ctoc() { char c=_cmd[_cnt]; if(_cnt<=_length) { ++_cnt; }else{untested(); } return c; } /*--------------------------------------------------------------------------*/ /* ctostr: character input to string * scan (and eat) an input string (cmd) using index (cnt). * result in (des) (null terminated). * max length (actual char count) is (len). * (des) must be at least (len)+1 characters long. * (cmd) unchanged. (*cnt) updated to point to next argument. * skips leading whitespace. skips trailing whitespace and comma * skips parts of input word too big for destination */ void CS::ctostr(char* des, int len, const std::string& term) { skipbl(); int ii; for (ii = 0; ii < len && !is_term(term); ++ii) { des[ii] = ctoc(); } des[ii] = '\0'; while (!is_term(term)) {untested(); skip(); } skipcom(); } /*--------------------------------------------------------------------------*/ std::string CS::ctos(const std::string& term, const std::string& begin_quote, const std::string& end_quote, const std::string& trap) { assert(begin_quote.length() == end_quote.length()); skipbl(); unsigned begin_string = cursor(); unsigned end_string = cursor(); std::string s; std::string::size_type which_quote = find1(begin_quote); if (which_quote != std::string::npos) { int quotes = 1; skip(); // the quote begin_string = cursor(); char the_begin_quote = begin_quote[which_quote]; char the_end_quote = end_quote[which_quote]; for (;;) { if (!ns_more()) {itested(); end_string = cursor(); warn(bDANGER, std::string("need ") + the_end_quote); break; }else if (skip1(the_end_quote)) { if (--quotes <= 0) { end_string = cursor() - 1; break; }else{ } }else if (skip1(the_begin_quote)) { ++quotes; skip(); }else if (skip1('\\')) { end_string = cursor() - 1; s += _cmd.substr(begin_string, end_string-begin_string); begin_string = cursor(); skip1(the_end_quote); }else{ skip(); } } s += _cmd.substr(begin_string, end_string-begin_string); }else{ while(ns_more() && !is_term(term)) { skip(); } if (match1(trap)) {untested(); warn(bDANGER, "ap_convert trap-exit"); }else{ } end_string = cursor(); s = _cmd.substr(begin_string, end_string-begin_string); } skipcom(); _ok = end_string > begin_string; return s; } /*--------------------------------------------------------------------------*/ std::string CS::get_to(const std::string& term) { std::string des; while(ns_more() && !match1(term)) { des += ctoc(); } return des; } /*--------------------------------------------------------------------------*/ /* ctob: character input to bool * no match makes it true; * Mismatch belongs to next token */ bool CS::ctob() { skipbl(); unsigned here = cursor(); bool val = true; ONE_OF || Set(*this, "1", &val, true) || Set(*this, "0", &val, false) || Set(*this, "t{rue}", &val, true) || Set(*this, "f{alse}", &val, false) || Set(*this, "y{es}", &val, true) || Set(*this, "n{o}", &val, false) || Set(*this, "#t{rue}", &val, true) || Set(*this, "#f{alse}",&val, false) ; skipcom(); _ok = cursor() > here; return val; } /*--------------------------------------------------------------------------*/ /* ctoi: character input to integer * Returns signed integer, or 0 if the string is not a number. * Input must be integer: no multipliers, no decimal point. * Dot or letter belongs to the next token. */ int CS::ctoi() { int val = 0; int sign = 1; skipbl(); unsigned here = cursor(); if (skip1("-")) { sign = -1; }else{ skip1("+"); } while (is_digit()) { val = 10 * val + (ctoc()-'0'); } skipcom(); _ok = cursor() > here; return val * sign; } /*--------------------------------------------------------------------------*/ /* ctou: character input to unsigned integer * Returns unsigned integer, or 0 if the string is not a number. * Input must be integer: no multipliers, no decimal point. * Dot or letter belongs to the next token. */ unsigned CS::ctou() { unsigned val = 0; skipbl(); unsigned here = cursor(); while (is_digit()) { val = 10 * val + static_cast(ctoc()-'0'); } skipcom(); _ok = cursor() > here; return val; } /*--------------------------------------------------------------------------*/ /* ctoo: character octal input to integer * Returns integer, or 0 if the string is not a number. * Input must be integer: no multipliers, no decimal point. * Dot or letter belongs to the next token. * There is no check against '8' and '9'. */ int CS::ctoo() { int val = 0; skipbl(); unsigned here = cursor(); while (is_digit()) { val = 8 * val + (ctoc()-'0'); } skipcom(); _ok = cursor() > here; return val; } /*--------------------------------------------------------------------------*/ /* ctox: character hex input to unsigned integer * Returns integer, or 0 if the string is not a number. * Input must be hex integer: no multipliers, no decimal point. * Dot or letter belongs to the next token. */ int CS::ctox() {untested(); int val = 0; skipbl(); unsigned here = cursor(); while (is_xdigit()) {untested(); if (is_digit()) {untested(); val = 16 * val + (ctoc()-'0'); }else{untested(); val = 16 * val + (tolower(ctoc())-'a'+10); } } skipcom(); _ok = cursor() > here; return val; } /*--------------------------------------------------------------------------*/ /* ctof: floating point input * return double number if got, else 0 * supports letter multipliers (spice style) * skips trailing letters (10uhenries == 10u) * skips trailing spaces and one comma * pointer points to char following comma * or first non-space following number just got * or first non-space (if non-number) */ double CS::ctof() { double val = 0.0; double power = 1.0; int sign = 1; skipbl(); if (!is_float()) { skipcom(); _ok = false; return 0.; }else{ } if (skip1("-")) { // sign sign = -1; }else{ skip1("+"); } while (is_digit()) { // up to dec pt val = 10.0 * val + (ctoc()-'0'); } skip1("."); // dec pt while (is_digit()) { // after dec pt val = 10.0 * val + (ctoc()-'0'); power *= .1; } if (skip1("eE")) { // exponent: E form int expo = 0; int es = 1; if (skip1("-")) { es = -1; }else{ skip1("+"); } while (is_digit()) expo = 10 * expo + (ctoc()-'0'); expo *= es; power *= pow(10., expo); }else if ((OPT::units == uSPICE) && skip1("mM")) { // M is special if (skip1("eE")) { // meg power *= 1e6; }else if (skip1("iI")) { // mil power *= 25.4e-6; }else{ // plain m (milli) power *= 1e-3; } }else if (skip1("M")) { assert(OPT::units == uSI); power *= 1e6; }else if (skip1("m")) { assert(OPT::units == uSI); power *= 1e-3; }else if (skip1("uU")) { // other letters power *= 1e-6; }else if (skip1("nN")) { power *= 1e-9; }else if (skip1("p")) { power *= 1e-12; }else if (skip1("P")) { power *= ((OPT::units == uSI) ? (1e15) : 1e-12); }else if (skip1("fF")) { power *= 1e-15; }else if (skip1("kK")) { power *= 1e3; }else if (skip1("gG")) { power *= 1e9; }else if (skip1("tT")) { power *= 1e12; }else if (skip1("%")) {untested(); power *= 1e-2; }else{ } while (is_alpha()) { // skip letters skip(); } skipcom(); _ok = true; return (sign*val*power); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/ap_error.cc000066400000000000000000000052271145401216200137670ustar00rootroot00000000000000/*$Id: ap_error.cc,v 26.122 2009/09/23 11:23:50 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Error handler. */ //testing=script 2006.07.17 #include "u_opt.h" #include "ap.h" /*--------------------------------------------------------------------------*/ // CS & CS::check(int i, const string& s); // CS & CS::warn(int i, int c, const string& s); /*--------------------------------------------------------------------------*/ /* syntax_check: handle syntax errors * called on parsing an input string when nothing else matches. * if the rest of the line is nothing, just return * if comment, increment *cnt, so what is left is a valid comment string * otherwise, it is an error (the arrow pointing at the offending word) */ CS & CS::check(int badness, const std::string& message) { skipbl(); switch (peek()) { case '/': _ok = umatch("//"); skip(); break; case ';': case '\'': itested(); _ok = true; skip(); break; case '\0': _ok = true; break; default: _ok = false; warn(badness, message); break; } return *this; } /*--------------------------------------------------------------------------*/ /* syntax_msg: print syntax error message * echo a portion of the input with an arrow pointing to the current place */ CS & CS::warn(int badness, unsigned spot, const std::string& message) { if (badness >= OPT::picky) { if (spot < 40) { IO::error << _cmd.substr(0,70) << '\n'; IO::error.tab(spot); }else{ IO::error << _cmd.substr(0,15) << " ... " << _cmd.substr(spot-20, 56) << '\n'; IO::error.tab(40); } IO::error << "^ ? " + message + '\n'; }else{ } return *this; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/ap_get.cc000066400000000000000000000060271145401216200134140ustar00rootroot00000000000000/*$Id: ap_get.cc,v 26.85 2008/06/19 05:01:15 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * get value for matching keyword */ //testing=script 2006.07.17 #include "ap.h" /*--------------------------------------------------------------------------*/ /* special version of "get" for "bool" * so "nofoo" works as an equivalent to foo=false */ bool Get(CS& cmd, const std::string& key, bool* val) { if (cmd.umatch(key + ' ')) { if (cmd.skip1b('=')) {itested(); cmd >> *val; }else{ *val = true; } return true; }else if (cmd.umatch("no" + key)) { *val = false; return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ bool Get(CS& cmd, const std::string& key, int* val, AP_MOD mod, int scale) { if (cmd.umatch(key + " {=}")) { switch(mod) { case mNONE: *val = int(cmd.ctof()); break; case mSCALE: untested(); *val = int(cmd.ctof())*scale; break; case mOFFSET: untested(); *val = int(cmd.ctof())+scale; break; case mINVERT: untested(); *val = 1 / int(cmd.ctof()); break; case mPOSITIVE: untested(); *val = std::abs(int(cmd.ctof())); break; case mOCTAL: *val = cmd.ctoo(); break; case mHEX: untested(); *val = cmd.ctox(); break; } return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ bool Get(CS& cmd, const std::string& key, double* val, AP_MOD mod, double scale) { if (cmd.umatch(key + " {=}")) { switch(mod) { case mNONE: untested(); *val = cmd.ctof(); break; case mSCALE: untested(); *val = cmd.ctof()*scale; break; case mOFFSET: untested(); *val = cmd.ctof()+scale; break; case mINVERT: untested(); *val = 1 / cmd.ctof(); break; case mPOSITIVE: *val = std::abs(cmd.ctof()); break; case mOCTAL: untested(); *val = cmd.ctoo(); break; case mHEX: untested(); *val = cmd.ctox(); break; } return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/ap_match.cc000066400000000000000000000066351145401216200137360ustar00rootroot00000000000000/*$Id: ap_match.cc,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * string compare */ //testing=script 2006.07.17 #include "u_opt.h" #include "ap.h" /*--------------------------------------------------------------------------*/ /* umatch = universal match */ CS& CS::umatch(const std::string& s) { unsigned start = cursor(); skipbl(); unsigned begin_match = cursor(); const char* str2 = s.c_str(); bool optional = 0; for (;;) { if ((!*str2) || (*str2 == '|')) { _ok = true; break; }else if ((str2[0] == '\\') && (peek() == str2[1])) { skip(); str2 += 2; }else if ((!optional) && (*str2 == '{')) { ++str2; optional = true; }else if ((optional) && (*str2 == '}')) { ++str2; optional = false; }else if ((*str2 == ' ') && is_term()) { // blank in ref string matches anything that delimits tokens skipbl(); ++str2; }else if (peek() == *str2) { skip(); ++str2; }else if ((OPT::case_insensitive) && (tolower(peek()) == tolower(*str2))) { skip(); ++str2; }else if (optional) { while (*str2 != '}') { ++str2; } }else{ // mismatch const char* bar = strchr(str2, '|'); if (bar && (bar[-1] != '\\')) { str2 = bar+1; reset(start); }else{ _ok = false; break; } } } if (_ok) { _begin_match = begin_match; _end_match = cursor(); skipcom(); _ok = true; }else{ reset(start); _ok = false; } return *this; } /*--------------------------------------------------------------------------*/ CS& CS::scan(const std::string& s) { unsigned start = cursor(); for (;;) { if (umatch(s)) { // found it _ok = true; break; }else if (!more()) { // ran out reset(start); _ok = false; break; }else{ // skip and try again skiparg(); } } return *this; } /*--------------------------------------------------------------------------*/ std::string CS::last_match()const { return _cmd.substr(_begin_match, _end_match-_begin_match); } /*--------------------------------------------------------------------------*/ std::string CS::trimmed_last_match(const std::string& suf)const { unsigned real_end = _end_match; while (strchr(suf.c_str(), _cmd[real_end-1])) { --real_end; } return _cmd.substr(_begin_match, real_end-_begin_match); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/ap_skip.cc000066400000000000000000000075561145401216200136130ustar00rootroot00000000000000/*$Id: ap_skip.cc,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * collection of functions to skip input * all except skip1 skip leading whitespace, skip whatever is being skipped, * then skip trailing whitespace. */ //testing=script 2006.07.17 #include "ap.h" /*--------------------------------------------------------------------------*/ /* skipbl: skip whitespace. (any non-graphic character is ws) * =,(,) are also ws * update string pointer * pointer points to first non-space * does NOT update _ok flag */ CS& CS::skipbl() { while (peek() && (!isgraph(peek()))) { skip(); } return *this; } /*--------------------------------------------------------------------------*/ /* skip1b: skip 1 matching character and surrounding blanks * _ok = did it */ CS& CS::skip1b(char t) { skipbl(); skip1(t); skipbl(); return *this; } /*--------------------------------------------------------------------------*/ /* skip1: skip 1 character matching any in t * _ok = did it */ CS& CS::skip1(char t) { if (match1(t)) { skip(); assert(_ok); }else{ _ok = false; } return *this; } /*--------------------------------------------------------------------------*/ /* skip1b: skip 1 matching character and surrounding blanks * _ok = did it */ CS& CS::skip1b(const std::string& t) { skipbl(); skip1(t); skipbl(); return *this; } /*--------------------------------------------------------------------------*/ /* skip1: skip 1 character matching any in t * _ok = did it */ CS& CS::skip1(const std::string& t) { if (match1(t)) { skip(); assert(_ok); }else{ _ok = false; } return *this; } /*--------------------------------------------------------------------------*/ /* skiparg: skip an argument (maybe just a comma) * _ok = skipped something */ CS& CS::skiparg() { unsigned here = cursor(); if (!skipcom()) { if (peek()) { skip(); }else{ } while (is_alpha() || is_float() || is_argsym()) { skip(); } skipcom(); }else{untested(); // empty field, just a comma } _ok = cursor() > here; return *this; } /*--------------------------------------------------------------------------*/ /* skipto: skip to a character (one of ...) * _ok = skipped something */ CS& CS::skipto1(const std::string& t) {untested(); unsigned here = cursor(); while (ns_more() && !match1(t)) {untested(); skip(); } _ok = ns_more(); if (!_ok) {untested(); reset(here); }else{untested(); } return *this; } /*--------------------------------------------------------------------------*/ /* skipto: skip to a character (explicit) * _ok = skipped something */ CS& CS::skipto1(char c) { unsigned here = cursor(); while (ns_more() && !match1(c)) { skip(); } _ok = ns_more(); if (!_ok) {untested(); reset(here); }else{ } return *this; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bm.cc000066400000000000000000000171441145401216200125550ustar00rootroot00000000000000/*$Id: bm.cc,v 26.132 2009/11/24 04:26:37 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * behavioral modeling action base */ //testing=script 2006.07.13 #include "u_lang.h" #include "e_elemnt.h" #include "bm.h" /*--------------------------------------------------------------------------*/ const double _default_bandwidth (NOT_INPUT); const double _default_delay (0.); const double _default_phase (0.); const double _default_ooffset (0.); const double _default_ioffset (0.); const double _default_scale (1.); const double _default_tc1 (0.); const double _default_tc2 (0.); const double _default_ic (0.); /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_ACTION_BASE::EVAL_BM_ACTION_BASE(int c) :EVAL_BM_BASE(c), _bandwidth(_default_bandwidth), _delay(_default_delay), _phase(_default_phase), _ooffset(_default_ooffset), _ioffset(_default_ioffset), _scale(_default_scale), _tc1(_default_tc1), _tc2(_default_tc2), _ic(_default_ic) { } /*--------------------------------------------------------------------------*/ EVAL_BM_ACTION_BASE::EVAL_BM_ACTION_BASE(const EVAL_BM_ACTION_BASE& p) :EVAL_BM_BASE(p), _bandwidth(p._bandwidth), _delay(p._delay), _phase(p._phase), _ooffset(p._ooffset), _ioffset(p._ioffset), _scale(p._scale), _tc1(p._tc1), _tc2(p._tc2), _ic(p._ic) { } /*--------------------------------------------------------------------------*/ double EVAL_BM_ACTION_BASE::temp_adjust()const { double tempdiff = _temp_c - _tnom_c; return (_scale * (1 + _tc1*tempdiff + _tc2*tempdiff*tempdiff)); } /*--------------------------------------------------------------------------*/ void EVAL_BM_ACTION_BASE::tr_final_adjust(FPOLY1* y, bool f_is_value)const { if (f_is_value) { y->f1 = y->f0; y->f0 = 0.; }else{ } *y *= temp_adjust(); y->f0 += _ooffset; } /*--------------------------------------------------------------------------*/ void EVAL_BM_ACTION_BASE::tr_finish_tdv(ELEMENT* d, double val)const { d->_y[0] = FPOLY1(CPOLY1(ioffset(d->_y[0].x), 0., val)); tr_final_adjust(&(d->_y[0]), false); } /*--------------------------------------------------------------------------*/ void EVAL_BM_ACTION_BASE::ac_final_adjust(COMPLEX* y)const { if (_bandwidth != NOT_INPUT && _bandwidth != 0.) {untested(); assert(y->imag() == 0); double ratio = CKT_BASE::_sim->_freq / _bandwidth; double coeff = y->real() / (1.+(ratio*ratio)); *y = COMPLEX(coeff, -coeff * ratio); }else{ } if (_phase != 0.) {itested(); *y *= std::polar(1., _phase*DTOR); }else{ } if (_delay != 0.) {untested(); double ratio = CKT_BASE::_sim->_freq * _delay; if (ratio > 100000.) {untested(); error(bPICKY, "delay too long\n"); ratio = 0.; }else{untested(); } *y *= std::polar(1., -360.0 * DTOR * ratio); }else{ } } /*--------------------------------------------------------------------------*/ void EVAL_BM_ACTION_BASE::ac_final_adjust_with_temp(COMPLEX* y)const { *y *= temp_adjust(); ac_final_adjust(y); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_ACTION_BASE::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_ACTION_BASE* p = dynamic_cast(&x); bool rv = p && _bandwidth == p->_bandwidth && _delay == p->_delay && _phase == p->_phase && _ooffset == p->_ooffset && _ioffset == p->_ioffset && _scale == p->_scale && _tc1 == p->_tc1 && _tc2 == p->_tc2 && _ic == p->_ic && EVAL_BM_BASE::operator==(x); if (rv) {untested(); }else{ } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_ACTION_BASE::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { print_pair(o, lang, "bandwidth",_bandwidth,_bandwidth.has_hard_value()); print_pair(o, lang, "delay", _delay, _delay.has_hard_value()); print_pair(o, lang, "phase", _phase, _phase.has_hard_value()); print_pair(o, lang, "ioffset", _ioffset, _ioffset.has_hard_value()); print_pair(o, lang, "ooffset", _ooffset, _ooffset.has_hard_value()); print_pair(o, lang, "scale", _scale, _scale.has_hard_value()); print_pair(o, lang, "tc1", _tc1, _tc1.has_hard_value()); print_pair(o, lang, "tc2", _tc2, _tc2.has_hard_value()); print_pair(o, lang, "ic", _ic, _ic.has_hard_value()); COMMON_COMPONENT::print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ void EVAL_BM_ACTION_BASE::precalc_first(const CARD_LIST* Scope) { assert(Scope); COMMON_COMPONENT::precalc_first(Scope); _bandwidth.e_val(_default_bandwidth, Scope); _delay.e_val(_default_delay, Scope); _phase.e_val(_default_phase, Scope); _ooffset.e_val(_default_ooffset, Scope); _ioffset.e_val(_default_ioffset, Scope); _scale.e_val(_default_scale, Scope); _tc1.e_val(_default_tc1, Scope); _tc2.e_val(_default_tc2, Scope); _ic.e_val(_default_ic, Scope); } /*--------------------------------------------------------------------------*/ void EVAL_BM_ACTION_BASE::ac_eval(ELEMENT* d)const { tr_eval(d); d->_ev = d->_y[0].f1; ac_final_adjust(&(d->_ev)); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(CS& cmd) { return ONE_OF || Get(cmd, "bandwidth",&_bandwidth) || Get(cmd, "delay", &_delay) || Get(cmd, "phase", &_phase) || Get(cmd, "ioffset", &_ioffset) || Get(cmd, "ooffset", &_ooffset) || Get(cmd, "scale", &_scale) || Get(cmd, "tc1", &_tc1) || Get(cmd, "tc2", &_tc2) || Get(cmd, "ic", &_ic) || COMMON_COMPONENT::parse_params_obsolete_callback(cmd); ; } /*--------------------------------------------------------------------------*/ bool EVAL_BM_ACTION_BASE::has_ext_args()const { return (_bandwidth.has_hard_value() || _delay.has_hard_value() || _phase.has_hard_value() || _ooffset.has_hard_value() || _ioffset.has_hard_value() || _scale.has_hard_value() || _tc1.has_hard_value() || _tc2.has_hard_value() || _ic.has_hard_value()); } /*--------------------------------------------------------------------------*/ COMMON_COMPONENT* EVAL_BM_ACTION_BASE::parse_func_type(CS& cmd) { const COMMON_COMPONENT* p = (cmd.is_float() || cmd.match1('_') || cmd.skip1b('=')) ? bm_dispatcher["eval_bm_value"] : bm_dispatcher[cmd]; if (p) { p->skip_type_tail(cmd); return p->clone(); }else{ return NULL; } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bm.h000066400000000000000000000103241145401216200124100ustar00rootroot00000000000000/*$Id: bm.h,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * behavioral modeling base */ //testing=script 2006.07.13 #ifndef E_BM_H #define E_BM_H #include "e_compon.h" /*--------------------------------------------------------------------------*/ class SPLINE; class FPOLY1; /*--------------------------------------------------------------------------*/ class EVAL_BM_BASE : public COMMON_COMPONENT { protected: explicit EVAL_BM_BASE(int c=0) :COMMON_COMPONENT(c) {} explicit EVAL_BM_BASE(const EVAL_BM_BASE& p) :COMMON_COMPONENT(p) {} ~EVAL_BM_BASE() {} protected: // override virtual bool operator==(const COMMON_COMPONENT&)const{/*incomplete();*/return false;} bool has_tr_eval()const {return true;} bool has_ac_eval()const {return true;} bool use_obsolete_callback_parse()const {return true;} bool use_obsolete_callback_print()const {return true;} bool has_parse_params_obsolete_callback()const {return true;} }; /*--------------------------------------------------------------------------*/ class INTERFACE EVAL_BM_ACTION_BASE : public EVAL_BM_BASE { protected: PARAMETER _bandwidth; PARAMETER _delay; PARAMETER _phase; PARAMETER _ooffset; PARAMETER _ioffset; PARAMETER _scale; PARAMETER _tc1; PARAMETER _tc2; PARAMETER _ic; protected: explicit EVAL_BM_ACTION_BASE(int c=0); explicit EVAL_BM_ACTION_BASE(const EVAL_BM_ACTION_BASE& p); ~EVAL_BM_ACTION_BASE() {} double temp_adjust()const; void tr_final_adjust(FPOLY1* y, bool f_is_value)const; void tr_finish_tdv(ELEMENT* d, double val)const; void ac_final_adjust(COMPLEX* y)const; void ac_final_adjust_with_temp(COMPLEX* y)const; double uic(double x)const {return (CKT_BASE::_sim->uic_now()) ? _ic : x;} double ioffset(double x)const {return uic(x) + _ioffset;} public: // override virtual bool operator==(const COMMON_COMPONENT&)const; //COMPONENT_COMMON* clone()const; //COMPONENT_COMMON=0 void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void precalc_first(const CARD_LIST*); void ac_eval(ELEMENT*)const; virtual bool ac_too()const = 0; protected: // override virtual bool parse_params_obsolete_callback(CS&); public: bool has_ext_args()const; static COMMON_COMPONENT* parse_func_type(CS&); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ class EVAL_BM_VALUE : public EVAL_BM_ACTION_BASE { private: explicit EVAL_BM_VALUE(const EVAL_BM_VALUE& p):EVAL_BM_ACTION_BASE(p) {} public: explicit EVAL_BM_VALUE(int c=0) :EVAL_BM_ACTION_BASE(c) {} ~EVAL_BM_VALUE() {} private: // override virtual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_VALUE(*this);} void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; bool is_trivial()const; void precalc_first(const CARD_LIST*); void tr_eval(ELEMENT*)const; std::string name()const {itested();return "VALUE";} bool ac_too()const {return false;} bool parse_numlist(CS&); bool parse_params_obsolete_callback(CS&); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif src/bm_complex.cc000066400000000000000000000101101145401216200142660ustar00rootroot00000000000000/*$Id: bm_complex.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * behavioral modeling complex value * used with tc, etc, and conditionals */ //testing=script 2006.07.13 #include "e_elemnt.h" #include "bm.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class EVAL_BM_COMPLEX : public EVAL_BM_ACTION_BASE { private: COMPLEX _value; explicit EVAL_BM_COMPLEX(const EVAL_BM_COMPLEX& p); public: explicit EVAL_BM_COMPLEX(int c=0); ~EVAL_BM_COMPLEX() {} private: // override virtual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_COMPLEX(*this);} void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void tr_eval(ELEMENT*)const; void ac_eval(ELEMENT*)const; std::string name()const {return "complex";} bool ac_too()const {untested();return true;} bool parse_numlist(CS&); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_COMPLEX::EVAL_BM_COMPLEX(int c) :EVAL_BM_ACTION_BASE(c), _value(NOT_INPUT) { } /*--------------------------------------------------------------------------*/ EVAL_BM_COMPLEX::EVAL_BM_COMPLEX(const EVAL_BM_COMPLEX& p) :EVAL_BM_ACTION_BASE(p), _value(p._value) { } /*--------------------------------------------------------------------------*/ bool EVAL_BM_COMPLEX::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_COMPLEX* p = dynamic_cast(&x); bool rv = p && _value == p->_value && EVAL_BM_ACTION_BASE::operator==(x); if (rv) { untested(); } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_COMPLEX::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); o << name() << '(' << _value.real() << ',' << _value.imag() << ')'; EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ void EVAL_BM_COMPLEX::tr_eval(ELEMENT* d)const { tr_finish_tdv(d, _value.real()); } /*--------------------------------------------------------------------------*/ void EVAL_BM_COMPLEX::ac_eval(ELEMENT* d)const { d->_ev = _value; ac_final_adjust_with_temp(&(d->_ev)); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_COMPLEX::parse_numlist(CS& cmd) { unsigned here = cmd.cursor(); double real = NOT_VALID; double imag = 0.; cmd >> real >> imag; if (cmd.gotit(here)) { _value = COMPLEX(real,imag); return true; }else{ untested(); return false; } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_COMPLEX p1(CC_STATIC); DISPATCHER::INSTALL d1(&bm_dispatcher, "complex", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bm_cond.cc000066400000000000000000000237151145401216200135610ustar00rootroot00000000000000/*$Id: bm_cond.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * behavioral modeling conditionals * The conditions refer to types of analysis, type SIM_MODE in mode.h. * An array "_func" stores handles to commons specific to each mode. */ //testing=script 2006.07.13 #include "e_elemnt.h" #include "bm.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ static EVAL_BM_VALUE func_zero(CC_STATIC); /*--------------------------------------------------------------------------*/ class EVAL_BM_COND : public EVAL_BM_BASE { private: COMMON_COMPONENT* _func[sCOUNT]; bool _set[sCOUNT]; explicit EVAL_BM_COND(const EVAL_BM_COND& p); public: explicit EVAL_BM_COND(int c=0); ~EVAL_BM_COND(); private: // override virtual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_COND(*this);} void parse_common_obsolete_callback(CS&); void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void precalc_first(const CARD_LIST*); void expand(const COMPONENT*); COMMON_COMPONENT* deflate(); void precalc_last(const CARD_LIST*); void tr_eval(ELEMENT*d)const {assert(_func[d->_sim->sim_mode()]); _func[d->_sim->sim_mode()]->tr_eval(d);} void ac_eval(ELEMENT*d)const {assert(_func[s_AC]); _func[s_AC]->ac_eval(d);} TIME_PAIR tr_review(COMPONENT*d) {assert(_func[d->_sim->sim_mode()]); return _func[d->_sim->sim_mode()]->tr_review(d);} void tr_accept(COMPONENT*d) {assert(_func[d->_sim->sim_mode()]); _func[d->_sim->sim_mode()]->tr_accept(d);} std::string name()const {itested(); return "????";} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_COND::EVAL_BM_COND(int c) :EVAL_BM_BASE(c) { std::fill_n(_func, sCOUNT, static_cast(0)); std::fill_n(_set, sCOUNT, false); } /*--------------------------------------------------------------------------*/ EVAL_BM_COND::EVAL_BM_COND(const EVAL_BM_COND& p) :EVAL_BM_BASE(p) { for (int i=0; i(&x); bool rv = p && EVAL_BM_BASE::operator==(x); if (rv) {untested(); incomplete(); } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_COND::parse_common_obsolete_callback(CS& cmd) //used { unsigned here = cmd.cursor(); cmd.reset().skipbl(); bool is_source = cmd.match1("viVI") || (cmd.match1('.') && (cmd.umatch(".vso{urce} ") || cmd.umatch(".iso{urce} "))); cmd.reset(here); do { SIM_MODE mode(s_NONE); ONE_OF || Set(cmd, "ac", &mode, s_AC) || Set(cmd, "op", &mode, s_OP) || Set(cmd, "dc", &mode, s_DC) || Set(cmd, "tran{sient}",&mode, s_TRAN) || Set(cmd, "four{ier}", &mode, s_FOURIER) || Set(cmd, "else", &mode, s_NONE) || Set(cmd, "all", &mode, s_NONE) || (mode = s_NONE) ; if (_set[mode]) {itested(); cmd.warn(bWARNING, (mode != s_NONE) ? "duplicate mode" : "what's this?"); } COMMON_COMPONENT* c = EVAL_BM_ACTION_BASE::parse_func_type(cmd); if (!c) { // no match for func_type if (cmd.more()) { if (!cmd.match1("\"'{")) { // quoted means it is a parameter or expression // otherwise assume it's a "model", for now // it might not be, but we fix later c = bm_dispatcher.clone("eval_bm_model"); }else{ } if (!c) { c = bm_dispatcher.clone("eval_bm_value"); }else{ } }else{ // no more } }else{ // got bm function } if (is_source // Spice compatibility && mode == s_NONE // for sources, no condition implies "DC" && !_set[s_DC] && dynamic_cast(c)) { mode = s_DC; }else{ } if (c) { c->parse_common_obsolete_callback(cmd); //BUG//callback }else{ c = &func_zero; } assert(c); attach_common(c, &(_func[mode])); assert(_func[mode]); _set[mode] = true; if (cmd.is_end()) { break; } } while (cmd.more() && !cmd.stuck(&here)); // apply rules to determine states not explicitly specified if (!_func[s_OP] && _set[s_DC]) {attach_common(_func[s_DC], &(_func[s_OP]));} if (!_func[s_OP] && _set[s_NONE]) {attach_common(_func[s_NONE],&(_func[s_OP]));} if (!_func[s_OP] && _set[s_TRAN]) {untested();attach_common(_func[s_TRAN],&(_func[s_OP]));} if (!_func[s_OP]) {attach_common(&func_zero, &(_func[s_OP]));} if (!_func[s_DC] && _set[s_NONE]) {attach_common(_func[s_NONE],&(_func[s_DC]));} if (!_func[s_DC] && _set[s_OP]) {untested();attach_common(_func[s_OP], &(_func[s_DC]));} if (!_func[s_DC] && _set[s_TRAN]) {untested();attach_common(_func[s_TRAN],&(_func[s_DC]));} if (!_func[s_DC]) {attach_common(&func_zero, &(_func[s_DC]));} if (!_func[s_TRAN]&&_set[s_NONE]) {attach_common(_func[s_NONE],&(_func[s_TRAN]));} if (!_func[s_TRAN] && _set[s_DC]) {attach_common(_func[s_DC],&(_func[s_TRAN]));} if (!_func[s_TRAN] && _set[s_OP]) {untested();attach_common(_func[s_OP],&(_func[s_TRAN]));} if (!_func[s_TRAN]) {attach_common(&func_zero,&(_func[s_TRAN]));} if (!_func[s_FOURIER]) {attach_common(_func[s_TRAN],&(_func[s_FOURIER]));} const EVAL_BM_ACTION_BASE* c = prechecked_cast(_func[s_NONE]); if (!_func[s_AC] && _set[s_NONE] && (!is_source || c->ac_too())) {attach_common(_func[s_NONE],&(_func[s_AC]));} if (!_func[s_AC]) {attach_common(&func_zero, &(_func[s_AC]));} for (int i = 1; i < sCOUNT; ++i) { assert(_func[i]); } } /*--------------------------------------------------------------------------*/ void EVAL_BM_COND::expand(const COMPONENT* d) { EVAL_BM_BASE::expand(d); for (int i = 1; i < sCOUNT; ++i) { //BUG// makes unnecessary duplicates assert(_func[i]); COMMON_COMPONENT* new_common = _func[i]->clone(); new_common->expand(d); COMMON_COMPONENT* deflated_common = new_common->deflate(); if (deflated_common != _func[i]) { attach_common(deflated_common, &(_func[i])); }else{untested(); } } } /*--------------------------------------------------------------------------*/ // If all are the same, there is no use for the COND. // Return the one thing that is attached, so the caller can replace it. COMMON_COMPONENT* EVAL_BM_COND::deflate() { for (int i = 1; i < sCOUNT; ++i) { if (_func[i] != _func[s_NONE]) { // they are not all the same, don't deflate return this; } } // they are all the same. Take one of them. return _func[s_NONE]->deflate(); } /*--------------------------------------------------------------------------*/ void EVAL_BM_COND::precalc_first(const CARD_LIST* Scope) { //BUG// calls the individual precalc more than once // wastes time and makes multiple "has no value" warnings // when there should be only one COMMON_COMPONENT* did_this = NULL; for (int i = 1; i < sCOUNT; ++i) { assert(_func[i]); if (_func[i] != did_this) { _func[i]->precalc_first(Scope); did_this = _func[i]; }else{ // already did } } } /*--------------------------------------------------------------------------*/ void EVAL_BM_COND::precalc_last(const CARD_LIST* Scope) { //BUG// calls the individual precalc more than once // wastes time and makes multiple "has no value" warnings // when there should be only one COMMON_COMPONENT* did_this = NULL; for (int i = 1; i < sCOUNT; ++i) { assert(_func[i]); if (_func[i] != did_this) { _func[i]->precalc_last(Scope); did_this = _func[i]; }else{itested(); // already did } } } /*--------------------------------------------------------------------------*/ void EVAL_BM_COND::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); bool more = false; if (_set[s_NONE]) { _func[s_NONE]->print_common_obsolete_callback(o, lang); more = true; }else{ } for (int i = sCOUNT-1; i != s_NONE; --i) { if (_set[i]) { if (more) { o << ' '; }else{ } o << ' ' << static_cast(i) << ' '; _func[i]->print_common_obsolete_callback(o, lang); more = true; }else{ } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_COND p1(CC_STATIC); DISPATCHER::INSTALL d1(&bm_dispatcher, "eval_bm_cond", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bm_exp.cc000066400000000000000000000165251145401216200134330ustar00rootroot00000000000000/*$Id: bm_exp.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * SPICE compatible EXP */ //testing=script 2005.10.06 #include "e_elemnt.h" #include "u_lang.h" #include "bm.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ const double _default_iv (NOT_INPUT); const double _default_pv (NOT_INPUT); const double _default_td1 (0); const double _default_tau1 (0); const double _default_td2 (0); const double _default_tau2 (0); const double _default_period(BIGBIG); /*--------------------------------------------------------------------------*/ class EVAL_BM_EXP : public EVAL_BM_ACTION_BASE { private: PARAMETER _iv; // initial value PARAMETER _pv; // pulsed value PARAMETER _td1; // rise delay PARAMETER _tau1; // rise time constant PARAMETER _td2; // fall delay PARAMETER _tau2; // fall time constant PARAMETER _period; // repeat period PARAMETER _end; // marks the end of the list explicit EVAL_BM_EXP(const EVAL_BM_EXP& p); public: explicit EVAL_BM_EXP(int c=0); ~EVAL_BM_EXP() {} private: // override vitrual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_EXP(*this);} void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void precalc_first(const CARD_LIST*); void tr_eval(ELEMENT*)const; TIME_PAIR tr_review(COMPONENT*); std::string name()const {return "exp";} bool ac_too()const {return false;} bool parse_numlist(CS&); bool parse_params_obsolete_callback(CS&); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_EXP::EVAL_BM_EXP(int c) :EVAL_BM_ACTION_BASE(c), _iv(_default_iv), _pv(_default_pv), _td1(_default_td1), _tau1(_default_tau1), _td2(_default_td2), _tau2(_default_tau2), _period(_default_period), _end(NOT_VALID) { } /*--------------------------------------------------------------------------*/ EVAL_BM_EXP::EVAL_BM_EXP(const EVAL_BM_EXP& p) :EVAL_BM_ACTION_BASE(p), _iv(p._iv), _pv(p._pv), _td1(p._td1), _tau1(p._tau1), _td2(p._td2), _tau2(p._tau2), _period(p._period), _end(NOT_VALID) { } /*--------------------------------------------------------------------------*/ bool EVAL_BM_EXP::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_EXP* p = dynamic_cast(&x); bool rv = p && _iv== p->_iv && _pv== p->_pv && _td1== p->_td1 && _tau1== p->_tau1 && _td2== p->_td2 && _tau2== p->_tau2 && _period== p->_period && EVAL_BM_ACTION_BASE::operator==(x); if (rv) { untested(); } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_EXP::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); o << name(); print_pair(o, lang, "iv", _iv); print_pair(o, lang, "pv", _pv); print_pair(o, lang, "td1", _td1); print_pair(o, lang, "tau1", _tau1); print_pair(o, lang, "td2", _td2); print_pair(o, lang, "tau2", _tau2); print_pair(o, lang, "period",_period, _period.has_hard_value()); EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ void EVAL_BM_EXP::precalc_first(const CARD_LIST* Scope) { assert(Scope); EVAL_BM_ACTION_BASE::precalc_first(Scope); _iv.e_val(_default_iv, Scope); _pv.e_val(_default_pv, Scope); _td1.e_val(_default_td1, Scope); _tau1.e_val(_default_tau1, Scope); _td2.e_val(_default_td2, Scope); _tau2.e_val(_default_tau2, Scope); _period.e_val(_default_period, Scope); } /*--------------------------------------------------------------------------*/ void EVAL_BM_EXP::tr_eval(ELEMENT* d)const { double ev = _iv; for (double time = d->_sim->_time0; time >= 0; time -= _period) { if (time > _td1) { ev += (_pv - _iv) * (1. - exp(-(time-_td1)/_tau1)); }else{ } if (time > _td2) { ev += (_iv - _pv) * (1. - exp(-(time-_td2)/_tau2)); }else{ } } tr_finish_tdv(d, ev); } /*--------------------------------------------------------------------------*/ TIME_PAIR EVAL_BM_EXP::tr_review(COMPONENT* d) { double time = d->_sim->_time0; time += d->_sim->_dtmin * .01; // hack to avoid duplicate events from numerical noise double raw_time = time; if (0 < _period && _period < BIGBIG) { time = fmod(time,_period); }else{ } double time_offset = raw_time - time; double dt = NEVER; if (time > _td2) { d->_time_by.min_event(_period + time_offset); dt = (_tau2 > 0) ? _tau2 : NEVER; }else if (time > _td1) { d->_time_by.min_event(_td2 + time_offset); dt = (_tau1 > 0) ? _tau1 : NEVER; }else if (d->_sim->_time0 < _period) { d->_time_by.min_event(_td1 + time_offset); dt = NEVER; }else{ d->_time_by.min_event(_td1 + time_offset); dt = (_tau2 > 0) ? _tau2 : NEVER; } d->_time_by.min_error_estimate(d->_sim->_time0 + dt); return d->_time_by; } /*--------------------------------------------------------------------------*/ bool EVAL_BM_EXP::parse_numlist(CS& cmd) { unsigned start = cmd.cursor(); unsigned here = cmd.cursor(); for (PARAMETER* i = &_iv; i < &_end; ++i) { PARAMETER val(NOT_VALID); cmd >> val; if (cmd.stuck(&here)) { break; }else{ *i = val; untested(); } } if (cmd.gotit(start)) { untested(); } return cmd.gotit(start); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_EXP::parse_params_obsolete_callback(CS& cmd) { return ONE_OF || Get(cmd, "iv", &_iv) || Get(cmd, "pv", &_pv) || Get(cmd, "td1", &_td1) || Get(cmd, "tau1", &_tau1) || Get(cmd, "td2", &_td2) || Get(cmd, "tau2", &_tau2) || Get(cmd, "period", &_period) || EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd) ; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_EXP p1(CC_STATIC); DISPATCHER::INSTALL d1(&bm_dispatcher, "exp", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bm_fit.cc000066400000000000000000000167711145401216200134240ustar00rootroot00000000000000/*$Id: bm_fit.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * cubic spline bm function */ //testing=script 2006.04.18 #include "u_lang.h" #include "e_elemnt.h" #include "m_spline.h" #include "bm.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ const int _default_order (3); const double _default_below (NOT_INPUT); const double _default_above (NOT_INPUT); const double _default_delta (NOT_INPUT); const int _default_smooth(0); /*--------------------------------------------------------------------------*/ class EVAL_BM_FIT : public EVAL_BM_ACTION_BASE { private: PARAMETER _order; PARAMETER _below; PARAMETER _above; PARAMETER _delta; PARAMETER _smooth; std::vector,PARAMETER > > _table; SPLINE* _spline; explicit EVAL_BM_FIT(const EVAL_BM_FIT& p); public: explicit EVAL_BM_FIT(int c=0); ~EVAL_BM_FIT(); private: // override virtual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_FIT(*this);} void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void precalc_first(const CARD_LIST*); void precalc_last(const CARD_LIST*); void tr_eval(ELEMENT*)const; std::string name()const {return "fit";} bool ac_too()const {return false;} bool parse_numlist(CS&); bool parse_params_obsolete_callback(CS&); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_FIT::EVAL_BM_FIT(int c) :EVAL_BM_ACTION_BASE(c), _order(_default_order), _below(_default_below), _above(_default_above), _delta(_default_delta), _smooth(_default_smooth), _table(), _spline(0) { } /*--------------------------------------------------------------------------*/ EVAL_BM_FIT::EVAL_BM_FIT(const EVAL_BM_FIT& p) :EVAL_BM_ACTION_BASE(p), _order(p._order), _below(p._below), _above(p._above), _delta(p._delta), _smooth(p._smooth), _table(p._table), _spline(0) { } /*--------------------------------------------------------------------------*/ EVAL_BM_FIT::~EVAL_BM_FIT() { delete _spline; } /*--------------------------------------------------------------------------*/ bool EVAL_BM_FIT::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_FIT* p = dynamic_cast(&x); bool rv = p && _order == p->_order && _below == p->_below && _above == p->_above && _delta == p->_delta && _smooth == p->_smooth && _table == p->_table && EVAL_BM_ACTION_BASE::operator==(x); if (rv) { untested(); } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_FIT::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); o << name() << '('; for (std::vector,PARAMETER > >:: const_iterator p = _table.begin(); p != _table.end(); ++p) { o << p->first << ',' << p->second << ' '; } o << ')'; print_pair(o, lang, "order", _order); print_pair(o, lang, "below", _below, _below.has_hard_value()); print_pair(o, lang, "above", _above, _above.has_hard_value()); print_pair(o, lang, "delta", _delta, _delta.has_hard_value()); print_pair(o, lang, "smooth",_smooth,_smooth.has_hard_value()); EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ void EVAL_BM_FIT::precalc_first(const CARD_LIST* Scope) { assert(Scope); EVAL_BM_ACTION_BASE::precalc_first(Scope); _order.e_val(_default_order, Scope); _below.e_val(_default_below, Scope); _above.e_val(_default_above, Scope); _delta.e_val(_default_delta, Scope); _smooth.e_val(_default_smooth, Scope); for (std::vector,PARAMETER > >:: iterator p = _table.begin(); p != _table.end(); ++p) { p->first.e_val(0, Scope); p->second.e_val(0, Scope); } } /*--------------------------------------------------------------------------*/ void EVAL_BM_FIT::precalc_last(const CARD_LIST* Scope) { assert(Scope); EVAL_BM_ACTION_BASE::precalc_last(Scope); double last = -BIGBIG; for (std::vector,PARAMETER > >:: iterator p = _table.begin(); p != _table.end(); ++p) { if (last > p->first) {untested(); throw Exception_Precalc("FIT table is out of order: (" + to_string(last) + ", " + to_string(p->first) + ")\n"); }else{ } last = p->first; } delete _spline; double below = _below.has_hard_value() ? _below : NOT_INPUT; double above = _above.has_hard_value() ? _above : NOT_INPUT; _spline = new SPLINE(_table, below, above, _order); } /*--------------------------------------------------------------------------*/ void EVAL_BM_FIT::tr_eval(ELEMENT* d)const { d->_y[0] = _spline->at(d->_y[0].x); tr_final_adjust(&(d->_y[0]), d->f_is_value()); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_FIT::parse_numlist(CS& cmd) { unsigned start = cmd.cursor(); unsigned here = cmd.cursor(); for (;;) { unsigned start_of_pair = here; std::pair, PARAMETER > p; //cmd >> key >> value; cmd >> p.first; // key if (cmd.stuck(&here)) { // no more, graceful finish break; }else{ cmd >> p.second; // value if (cmd.stuck(&here)) { // ran out, but already have half of the pair // back up one, hoping somebody else knows what to do with it cmd.reset(start_of_pair); break; }else{ _table.push_back(p); } } } if (cmd.gotit(start)) { }else{ untested(); } return cmd.gotit(start); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_FIT::parse_params_obsolete_callback(CS& cmd) { return ONE_OF || Get(cmd, "order", &_order) || Get(cmd, "below", &_below) || Get(cmd, "above", &_above) || Get(cmd, "delta", &_delta) || Get(cmd, "smooth",&_smooth) || EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd) ; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_FIT p1(CC_STATIC); DISPATCHER::INSTALL d1(&bm_dispatcher, "fit", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bm_generator.cc000066400000000000000000000077201145401216200146220ustar00rootroot00000000000000/*$Id: bm_generator.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * behavioral modeling simple value * used with tc, etc, and conditionals */ //testing=script,complete 2005.10.06 #include "e_elemnt.h" #include "bm.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class EVAL_BM_GENERATOR : public EVAL_BM_ACTION_BASE { private: explicit EVAL_BM_GENERATOR(const EVAL_BM_GENERATOR& p); public: explicit EVAL_BM_GENERATOR(int c=0); ~EVAL_BM_GENERATOR() {} private: // override virtual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_GENERATOR(*this);} void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void tr_eval(ELEMENT*)const; void ac_eval(ELEMENT*)const; std::string name()const {return "generator";} bool ac_too()const {return true;} bool parse_numlist(CS&); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_GENERATOR::EVAL_BM_GENERATOR(int c) :EVAL_BM_ACTION_BASE(c) { } /*--------------------------------------------------------------------------*/ EVAL_BM_GENERATOR::EVAL_BM_GENERATOR(const EVAL_BM_GENERATOR& p) :EVAL_BM_ACTION_BASE(p) { } /*--------------------------------------------------------------------------*/ bool EVAL_BM_GENERATOR::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_GENERATOR* p = dynamic_cast(&x); bool rv = p && EVAL_BM_ACTION_BASE::operator==(x); if (rv) { incomplete(); untested(); } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_GENERATOR::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); o << name(); EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ void EVAL_BM_GENERATOR::tr_eval(ELEMENT* d)const { tr_finish_tdv(d, d->_sim->_genout); } /*--------------------------------------------------------------------------*/ void EVAL_BM_GENERATOR::ac_eval(ELEMENT* d)const { d->_ev = 1; ac_final_adjust_with_temp(&(d->_ev)); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_GENERATOR::parse_numlist(CS& cmd) { unsigned here = cmd.cursor(); PARAMETER new_value(NOT_VALID); cmd >> new_value; if (cmd.gotit(here)) { _scale = new_value; return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_GENERATOR p1(CC_STATIC); DISPATCHER::INSTALL d1(&bm_dispatcher, "gen|generator", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bm_model.cc000066400000000000000000000116461145401216200137360ustar00rootroot00000000000000/*$Id: bm_model.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * behavioral modeling ".model" stub * accepts an unknown name for later linking to a .model */ //testing=script 2006.07.13 #include "e_model.h" #include "bm.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class EVAL_BM_MODEL : public EVAL_BM_ACTION_BASE { private: std::string _arglist; COMMON_COMPONENT* _func; explicit EVAL_BM_MODEL(const EVAL_BM_MODEL& p); public: explicit EVAL_BM_MODEL(int c=0); ~EVAL_BM_MODEL() {detach_common(&_func);} private: // override virtual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_MODEL(*this);} void parse_common_obsolete_callback(CS&); void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void expand(const COMPONENT*); COMMON_COMPONENT* deflate() {return (_func) ? _func->deflate() : this;} void tr_eval(ELEMENT*d)const {assert(_func); _func->tr_eval(d);} void ac_eval(ELEMENT*d)const {assert(_func); _func->ac_eval(d);} std::string name()const {itested();return modelname();} bool ac_too()const {return true;} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_MODEL::EVAL_BM_MODEL(int c) :EVAL_BM_ACTION_BASE(c), _arglist(), _func(0) { } /*--------------------------------------------------------------------------*/ EVAL_BM_MODEL::EVAL_BM_MODEL(const EVAL_BM_MODEL& p) :EVAL_BM_ACTION_BASE(p), _arglist(p._arglist), _func(0) { attach_common(p._func, &_func); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_MODEL::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_MODEL* p = dynamic_cast(&x); bool rv = p && _arglist == p->_arglist && EVAL_BM_ACTION_BASE::operator==(x); if (rv) { incomplete(); untested(); } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_MODEL::parse_common_obsolete_callback(CS& cmd) //used { assert(!_func); assert(!has_model()); parse_modelname(cmd); _arglist = cmd.ctos("", "(", ")"); assert(!_func); } /*--------------------------------------------------------------------------*/ void EVAL_BM_MODEL::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); if (_func) { _func->print_common_obsolete_callback(o, lang); }else{ o << modelname(); if (_arglist != "") {untested(); o << "(" << _arglist << ")"; }else{ } } } /*--------------------------------------------------------------------------*/ void EVAL_BM_MODEL::expand(const COMPONENT* d) { EVAL_BM_ACTION_BASE::expand(d); // not sure what kind of model it is yet. // see what we find. COMMON_COMPONENT* c = NULL; try { attach_model(d); assert(has_model()); c = dynamic_cast(model()->new_common()); }catch (Exception& e) { error(bTRACE, e.message() + "++++\n"); assert(!has_model()); c = bm_dispatcher.clone("eval_bm_value"); } if (!c) { throw Exception(d->long_label() + ": model type mismatch"); //BUG// memory leak }else{ } // now we have one // link to the real one // later, a "deflate" will push it down to proper place. c->set_modelname(modelname()); CS args(CS::_STRING, _arglist); c->parse_common_obsolete_callback(args); c->expand(d); attach_common(c, &_func); assert(_func); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_MODEL p1(CC_STATIC); DISPATCHER::INSTALL d1(&bm_dispatcher, "eval_bm_model", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bm_poly.cc000066400000000000000000000137501145401216200136170ustar00rootroot00000000000000/*$Id: bm_poly.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * HSPICE compatible POLY */ //testing=script,complete 2005.10.06 #include "u_lang.h" #include "e_elemnt.h" #include "bm.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ const double _default_max(BIGBIG); const double _default_min(-BIGBIG); const bool _default_abs(false); /*--------------------------------------------------------------------------*/ class EVAL_BM_POLY : public EVAL_BM_ACTION_BASE { private: PARAMETER _min; PARAMETER _max; PARAMETER _abs; std::vector > _c; explicit EVAL_BM_POLY(const EVAL_BM_POLY& p); public: explicit EVAL_BM_POLY(int c=0); ~EVAL_BM_POLY() {} private: // override vitrual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_POLY(*this);} void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void precalc_first(const CARD_LIST*); void tr_eval(ELEMENT*)const; std::string name()const {return "poly";} bool ac_too()const {untested();return false;} bool parse_numlist(CS&); bool parse_params_obsolete_callback(CS&); void skip_type_tail(CS& cmd)const {cmd.umatch("(1)");} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_POLY::EVAL_BM_POLY(int c) :EVAL_BM_ACTION_BASE(c), _min(_default_min), _max(_default_max), _abs(_default_abs) { } /*--------------------------------------------------------------------------*/ EVAL_BM_POLY::EVAL_BM_POLY(const EVAL_BM_POLY& p) :EVAL_BM_ACTION_BASE(p), _min(p._min), _max(p._max), _abs(p._abs), _c(p._c) { } /*--------------------------------------------------------------------------*/ bool EVAL_BM_POLY::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_POLY* p = dynamic_cast(&x); bool rv = p && _min == p->_min && _max == p->_max && _abs == p->_abs && _c == p->_c && EVAL_BM_ACTION_BASE::operator==(x); if (rv) { incomplete(); untested(); } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_POLY::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); o << name() << '('; for (std::vector >::const_iterator p = _c.begin(); p != _c.end(); ++p) { o << *p << ' '; } o << ')'; print_pair(o, lang, "min", _min, _min.has_hard_value()); print_pair(o, lang, "max", _max, _max.has_hard_value()); print_pair(o, lang, "abs", _abs, _abs.has_hard_value()); EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ void EVAL_BM_POLY::precalc_first(const CARD_LIST* Scope) { assert(Scope); EVAL_BM_ACTION_BASE::precalc_first(Scope); for (std::vector >::const_iterator p = _c.begin(); p != _c.end(); ++p) { (*p).e_val(0, Scope); } _min.e_val(_default_min, Scope); _max.e_val(_default_max, Scope); _abs.e_val(_default_abs, Scope); } /*--------------------------------------------------------------------------*/ void EVAL_BM_POLY::tr_eval(ELEMENT* d)const { double x = ioffset(d->_y[0].x); double f0 = 0.; double f1 = 0.; for (size_t i=_c.size()-1; i>0; --i) { f0 += _c[i]; f0 *= x; f1 *= x; f1 += _c[i]*int(i); } f0 += _c[0]; if (_abs && f0 < 0) { f0 = -f0; f1 = -f1; } if (f0 > _max) { f0 = _max; f1 = 0; }else if (f0 < _min) { f0 = _min; f1 = 0; } d->_y[0] = FPOLY1(x, f0, f1); tr_final_adjust(&(d->_y[0]), d->f_is_value()); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_POLY::parse_numlist(CS& cmd) { unsigned start = cmd.cursor(); unsigned here = cmd.cursor(); for (;;) { unsigned old_here = here; PARAMETER val; cmd >> val; if (cmd.stuck(&here)) { // no more, graceful finish break; }else{ if (cmd.match1('=')) { // got one that doesn't belong, back up cmd.reset(old_here); break; }else{ _c.push_back(val); } } } if (cmd.gotit(start)) { }else{ untested(); } return cmd.gotit(start); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_POLY::parse_params_obsolete_callback(CS& cmd) { return ONE_OF || Get(cmd, "min", &_min) || Get(cmd, "max", &_max) || Get(cmd, "abs", &_abs) || EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd) ; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_POLY p1(CC_STATIC); DISPATCHER::INSTALL d1(&bm_dispatcher, "poly", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bm_posy.cc000066400000000000000000000171241145401216200136250ustar00rootroot00000000000000/*$Id: bm_posy.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * behavioral modeling - posynomial (non-integer powers) * pair ... first is key, second is value */ //testing=script 2005.10.06 #include "u_lang.h" #include "e_elemnt.h" #include "bm.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ const double _default_max(BIGBIG); const double _default_min(-BIGBIG); const bool _default_abs(false); const bool _default_odd(false); const bool _default_even(false); /*--------------------------------------------------------------------------*/ class EVAL_BM_POSY : public EVAL_BM_ACTION_BASE { private: PARAMETER _min; PARAMETER _max; PARAMETER _abs; PARAMETER _odd; PARAMETER _even; std::vector,PARAMETER > > _table; explicit EVAL_BM_POSY(const EVAL_BM_POSY& p); public: explicit EVAL_BM_POSY(int c=0); ~EVAL_BM_POSY() {} private: // override vitrual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_POSY(*this);} void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void precalc_first(const CARD_LIST*); void tr_eval(ELEMENT*)const; std::string name()const {return "posy";} bool ac_too()const {untested();return false;} bool parse_numlist(CS&); bool parse_params_obsolete_callback(CS&); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_POSY::EVAL_BM_POSY(int c) :EVAL_BM_ACTION_BASE(c), _min(_default_min), _max(_default_max), _abs(_default_abs), _odd(_default_odd), _even(_default_even), _table() { } /*--------------------------------------------------------------------------*/ EVAL_BM_POSY::EVAL_BM_POSY(const EVAL_BM_POSY& p) :EVAL_BM_ACTION_BASE(p), _min(p._min), _max(p._max), _abs(p._abs), _odd(p._odd), _even(p._even), _table(p._table) { } /*--------------------------------------------------------------------------*/ bool EVAL_BM_POSY::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_POSY* p = dynamic_cast(&x); bool rv = p && _min == p->_min && _max == p->_max && _abs == p->_abs && _odd == p->_odd && _even == p->_even && _table == p->_table && EVAL_BM_ACTION_BASE::operator==(x); if (rv) { untested(); } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_POSY::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); o << name() << '('; for (std::vector,PARAMETER > >:: const_iterator p = _table.begin(); p != _table.end(); ++p) { o << p->second << ',' << p->first << ' '; } o << ')'; print_pair(o, lang, "min", _min, _min.has_hard_value()); print_pair(o, lang, "max", _max, _max.has_hard_value()); print_pair(o, lang, "abs", _abs, _abs.has_hard_value()); print_pair(o, lang, "odd", _odd, _odd.has_hard_value()); print_pair(o, lang, "even",_even,_even.has_hard_value()); EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ void EVAL_BM_POSY::precalc_first(const CARD_LIST* Scope) { assert(Scope); EVAL_BM_ACTION_BASE::precalc_first(Scope); _min.e_val(_default_min, Scope); _max.e_val(_default_max, Scope); _abs.e_val(_default_abs, Scope); _odd.e_val(_default_odd, Scope); _even.e_val(_default_even, Scope); for (std::vector,PARAMETER > >:: iterator p = _table.begin(); p != _table.end(); ++p) { p->first.e_val(0, Scope); p->second.e_val(0, Scope); } } /*--------------------------------------------------------------------------*/ void EVAL_BM_POSY::tr_eval(ELEMENT* d)const { double x_raw = ioffset(d->_y[0].x); trace1("before", x_raw); double x = (x_raw < 0) ? ((_odd || _even) ? -x_raw : 0.) : x_raw; assert(x >= 0); trace1("rev", x); double f0 = 0.; double f1 = 0.; if (x > 0) { for (std::vector,PARAMETER > >:: const_iterator p = _table.begin(); p != _table.end(); ++p) { double coeff = p->second * pow(x, p->first-1); f1 += coeff * p->first; f0 += coeff * x; } }else{ assert(x == 0); for (std::vector,PARAMETER > >:: const_iterator p = _table.begin(); p != _table.end(); ++p) { if (p->first == 0.) { f0 += 1; untested(); } } } trace3("", x, f0, f1); if (_odd && x_raw < 0) { f0 = -f0; } if (_even && x_raw < 0) { f1 = -f1; untested(); } trace3("after", x, f0, f1); if (_abs && f0 < 0) { f0 = -f0; f1 = -f1; untested(); } if (f0 > _max) { f0 = _max; f1 = 0; untested(); }else if (f0 < _min) { f0 = _min; f1 = 0; untested(); } d->_y[0] = FPOLY1(x_raw, f0, f1); tr_final_adjust(&(d->_y[0]), d->f_is_value()); trace3("fa", d->_y[0].x, d->_y[0].f0, d->_y[0].f1); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_POSY::parse_numlist(CS& cmd) { unsigned start = cmd.cursor(); unsigned here = cmd.cursor(); for (;;) { unsigned start_of_pair = here; std::pair, PARAMETER > p; cmd >> p.second; // value if (cmd.stuck(&here)) { // no more, graceful finish break; }else{ cmd >> p.first; // key if (cmd.stuck(&here)) { // ran out, but already have half of the pair // back up one, hoping somebody else knows what to do with it cmd.reset(start_of_pair); break; }else{ _table.push_back(p); } } } if (cmd.gotit(start)) { }else{ untested(); } return cmd.gotit(start); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_POSY::parse_params_obsolete_callback(CS& cmd) { return ONE_OF || Get(cmd, "min", &_min) || Get(cmd, "max", &_max) || Get(cmd, "abs", &_abs) || Get(cmd, "odd", &_odd) || Get(cmd, "even", &_even) || EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd) ; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_POSY p1(CC_STATIC); DISPATCHER::INSTALL d1(&bm_dispatcher, "posy", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bm_pulse.cc000066400000000000000000000176461145401216200137740ustar00rootroot00000000000000/*$Id: bm_pulse.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * SPICE compatible PULSE */ //testing=script 2005.10.06 #include "e_elemnt.h" #include "u_lang.h" #include "bm.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ const double _default_iv (NOT_INPUT); const double _default_pv (NOT_INPUT); const double _default_delay (0); const double _default_rise (0); const double _default_fall (0); const double _default_width (BIGBIG); const double _default_period(BIGBIG); /*--------------------------------------------------------------------------*/ class EVAL_BM_PULSE : public EVAL_BM_ACTION_BASE { private: PARAMETER _iv; PARAMETER _pv; PARAMETER _delay; PARAMETER _rise; PARAMETER _fall; PARAMETER _width; PARAMETER _period; PARAMETER _end; explicit EVAL_BM_PULSE(const EVAL_BM_PULSE& p); public: explicit EVAL_BM_PULSE(int c=0); ~EVAL_BM_PULSE() {} private: // override vitrual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_PULSE(*this);} void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void precalc_first(const CARD_LIST*); void tr_eval(ELEMENT*)const; TIME_PAIR tr_review(COMPONENT*); std::string name()const {return "pulse";} bool ac_too()const {return false;} bool parse_numlist(CS&); bool parse_params_obsolete_callback(CS&); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_PULSE::EVAL_BM_PULSE(int c) :EVAL_BM_ACTION_BASE(c), _iv(_default_iv), _pv(_default_pv), _delay(_default_delay), _rise(_default_rise), _fall(_default_fall), _width(_default_width), _period(_default_period), _end(NOT_VALID) { } /*--------------------------------------------------------------------------*/ EVAL_BM_PULSE::EVAL_BM_PULSE(const EVAL_BM_PULSE& p) :EVAL_BM_ACTION_BASE(p), _iv(p._iv), _pv(p._pv), _delay(p._delay), _rise(p._rise), _fall(p._fall), _width(p._width), _period(p._period), _end(NOT_VALID) { } /*--------------------------------------------------------------------------*/ bool EVAL_BM_PULSE::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_PULSE* p = dynamic_cast(&x); bool rv = p && _iv == p->_iv && _pv == p->_pv && _delay == p->_delay && _rise == p->_rise && _fall == p->_fall && _width == p->_width && _period == p->_period && EVAL_BM_ACTION_BASE::operator==(x); if (rv) { untested(); } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_PULSE::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); o << name(); print_pair(o, lang, "iv", _iv); print_pair(o, lang, "pv", _pv); print_pair(o, lang, "delay", _delay); print_pair(o, lang, "rise", _rise); print_pair(o, lang, "fall", _fall); print_pair(o, lang, "width", _width); print_pair(o, lang, "period", _period); EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ void EVAL_BM_PULSE::precalc_first(const CARD_LIST* Scope) { assert(Scope); EVAL_BM_ACTION_BASE::precalc_first(Scope); _iv.e_val(_default_iv, Scope); _pv.e_val(_default_pv, Scope); _delay.e_val(_default_delay, Scope); _rise.e_val(_default_rise, Scope); _fall.e_val(_default_fall, Scope); _width.e_val(_default_width, Scope); _period.e_val(_default_period, Scope); if (_width == 0.) {untested(); _width = _default_width; }else{ } if (_period == 0.) {untested(); _period = _default_period; }else{ } } /*--------------------------------------------------------------------------*/ void EVAL_BM_PULSE::tr_eval(ELEMENT* d)const { double time = d->_sim->_time0; if (0 < _period && _period < BIGBIG) { //time = fmod(time,_period); if (time > _delay) { time = fmod(time - _delay, _period) + _delay; }else{ } }else{ } double ev = 0; // effective value if (time >= _delay+_rise+_width+_fall) { /* past pulse */ ev = _iv; }else if (time >= _delay+_rise+_width) { /* falling */ double interp = (time - (_delay+_rise+_width)) / _fall; ev = _pv + interp * (_iv - _pv); }else if (time >= _delay + _rise) { /* pulse val */ ev = _pv; }else if (time >= _delay) { /* rising */ double interp = (time - _delay) / _rise; ev = _iv + interp * (_pv - _iv); }else{ /* init val */ ev = _iv; } //d->q_accept(); tr_finish_tdv(d, ev); } /*--------------------------------------------------------------------------*/ TIME_PAIR EVAL_BM_PULSE::tr_review(COMPONENT* d) { double time = d->_sim->_time0; time += d->_sim->_dtmin * .01; // hack to avoid duplicate events from numerical noise double raw_time = time; if (0 < _period && _period < BIGBIG) { if (time > _delay) { time = fmod(time - _delay, _period) + _delay; }else{ } }else{ } double time_offset = raw_time - time; if (time >= _delay+_rise+_width+_fall) { /* past pulse */ d->_time_by.min_event(_delay + _period + time_offset); }else if (time >= _delay+_rise+_width) { /* falling */ d->_time_by.min_event(_delay + _rise + _width + _fall + time_offset); }else if (time >= _delay + _rise) { /* pulse val */ d->_time_by.min_event(_delay + _rise + _width + time_offset); }else if (time >= _delay) { /* rising */ d->_time_by.min_event(_delay + _rise + time_offset); }else{ /* init val */ d->_time_by.min_event(_delay + time_offset); } return d->_time_by; } /*--------------------------------------------------------------------------*/ bool EVAL_BM_PULSE::parse_numlist(CS& cmd) { unsigned start = cmd.cursor(); unsigned here = cmd.cursor(); for (PARAMETER* i = &_iv; i < &_end; ++i) { PARAMETER val(NOT_VALID); cmd >> val; if (cmd.stuck(&here)) { break; }else{ *i = val; } } return cmd.gotit(start); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_PULSE::parse_params_obsolete_callback(CS& cmd) { return ONE_OF || Get(cmd, "iv", &_iv) || Get(cmd, "pv", &_pv) || Get(cmd, "delay", &_delay) || Get(cmd, "rise", &_rise) || Get(cmd, "fall", &_fall) || Get(cmd, "width", &_width) || Get(cmd, "period", &_period) || EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd) ; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_PULSE p1(CC_STATIC); DISPATCHER::INSTALL d1(&bm_dispatcher, "pulse", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bm_pwl.cc000066400000000000000000000170121145401216200134310ustar00rootroot00000000000000/*$Id: bm_pwl.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * HSPICE compatible PWL */ //testing=script 2005.10.06 #include "u_lang.h" #include "e_elemnt.h" #include "m_interp.h" #include "bm.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ const double _default_delta (NOT_INPUT); const int _default_smooth(0); /*--------------------------------------------------------------------------*/ class EVAL_BM_PWL : public EVAL_BM_ACTION_BASE { private: PARAMETER _delta; PARAMETER _smooth; std::vector,PARAMETER > > _raw_table; std::vector _num_table; explicit EVAL_BM_PWL(const EVAL_BM_PWL& p); public: explicit EVAL_BM_PWL(int c=0); ~EVAL_BM_PWL() {} private: // override virtual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_PWL(*this);} void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void precalc_first(const CARD_LIST*); void precalc_last(const CARD_LIST*); void tr_eval(ELEMENT*)const; TIME_PAIR tr_review(COMPONENT*); std::string name()const {return "pwl";} bool ac_too()const {return false;} bool parse_numlist(CS&); bool parse_params_obsolete_callback(CS&); void skip_type_tail(CS& cmd)const {cmd.umatch("(1)");} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_PWL::EVAL_BM_PWL(int c) :EVAL_BM_ACTION_BASE(c), _delta(_default_delta), _smooth(_default_smooth), _raw_table(), _num_table() { } /*--------------------------------------------------------------------------*/ EVAL_BM_PWL::EVAL_BM_PWL(const EVAL_BM_PWL& p) :EVAL_BM_ACTION_BASE(p), _delta(p._delta), _smooth(p._smooth), _raw_table(p._raw_table), _num_table(p._num_table) { } /*--------------------------------------------------------------------------*/ bool EVAL_BM_PWL::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_PWL* p = dynamic_cast(&x); bool rv = p && _delta == p->_delta && _smooth == p->_smooth && _raw_table == p->_raw_table && _num_table == p->_num_table && EVAL_BM_ACTION_BASE::operator==(x); if (rv) { untested(); } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_PWL::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); o << name() << '('; for (std::vector,PARAMETER > >:: const_iterator p = _raw_table.begin(); p != _raw_table.end(); ++p) { o << p->first << ',' << p->second << ' '; } o << ')'; print_pair(o, lang, "delta", _delta, _delta.has_hard_value()); print_pair(o, lang, "smooth",_smooth,_smooth.has_hard_value()); EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ void EVAL_BM_PWL::precalc_first(const CARD_LIST* Scope) { assert(Scope); EVAL_BM_ACTION_BASE::precalc_first(Scope); _delta.e_val(_default_delta, Scope); _smooth.e_val(_default_smooth, Scope); for (std::vector,PARAMETER > >::iterator p = _raw_table.begin(); p != _raw_table.end(); ++p) { p->first.e_val(0, Scope); p->second.e_val(0, Scope); } } /*--------------------------------------------------------------------------*/ void EVAL_BM_PWL::precalc_last(const CARD_LIST* Scope) { assert(Scope); EVAL_BM_ACTION_BASE::precalc_last(Scope); double last = -BIGBIG; for (std::vector,PARAMETER > >::iterator p = _raw_table.begin(); p != _raw_table.end(); ++p) { if (last > p->first) { throw Exception_Precalc("PWL is out of order: (" + to_string(last) + ", " + to_string(p->first) + ")\n"); }else{ DPAIR x(p->first, p->second); _num_table.push_back(x); } last = p->first; } } /*--------------------------------------------------------------------------*/ void EVAL_BM_PWL::tr_eval(ELEMENT* d)const { double ext = (d->is_source()) ? 0. : NOT_INPUT; d->_y[0] = interpolate(_num_table.begin(), _num_table.end(), ioffset(d->_y[0].x), ext, ext); tr_final_adjust(&(d->_y[0]), d->f_is_value()); } /*--------------------------------------------------------------------------*/ TIME_PAIR EVAL_BM_PWL::tr_review(COMPONENT* d) { if (d->is_source()) { // index (x) is time ELEMENT* dd = prechecked_cast(d); assert(dd); double x = dd->_y[0].x + d->_sim->_dtmin * .01; DPAIR here(x, BIGBIG); std::vector::iterator begin = _num_table.begin(); std::vector::iterator end = _num_table.end(); std::vector::iterator upper = upper_bound(begin, end, here); std::vector::iterator lower = upper - 1; assert(x > lower->first); d->_time_by.min_event((x < upper->first) ? upper->first : NEVER); }else{untested(); // index (x) is input // It's really needed here too, more work needed } return d->_time_by; } /*--------------------------------------------------------------------------*/ bool EVAL_BM_PWL::parse_numlist(CS& cmd) { unsigned start = cmd.cursor(); unsigned here = cmd.cursor(); for (;;) { unsigned start_of_pair = here; std::pair, PARAMETER > p; //cmd >> key >> value; cmd >> p.first; // key if (cmd.stuck(&here)) { // no more, graceful finish break; }else{ cmd >> p.second; // value if (cmd.stuck(&here)) { // ran out, but already have half of the pair // back up one, hoping somebody else knows what to do with it cmd.reset(start_of_pair); break; }else{ _raw_table.push_back(p); } } } if (cmd.gotit(start)) { }else{ untested(); } return cmd.gotit(start); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_PWL::parse_params_obsolete_callback(CS& cmd) { return ONE_OF || Get(cmd, "delta", &_delta) || Get(cmd, "smooth", &_smooth) || EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd) ; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_PWL p1(CC_STATIC); DISPATCHER::INSTALL d1(&bm_dispatcher, "pwl", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bm_sffm.cc000066400000000000000000000200421145401216200135570ustar00rootroot00000000000000/*$Id: bm_sffm.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * SPICE compatible SFFM */ //testing=script 2005.10.07 #include "e_elemnt.h" #include "l_denoise.h" #include "u_lang.h" #include "bm.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ const double _default_offset (0); const double _default_amplitude (1); const double _default_carrier (NOT_INPUT); const double _default_modindex (NOT_INPUT); const double _default_signal (NOT_INPUT); const double _default_samples (4); const bool _default_zero (true); const bool _default_peak (true); /*--------------------------------------------------------------------------*/ class EVAL_BM_SFFM : public EVAL_BM_ACTION_BASE { private: PARAMETER _offset; PARAMETER _amplitude; PARAMETER _carrier; PARAMETER _modindex; PARAMETER _signal; PARAMETER _end; PARAMETER _samples; PARAMETER _zero; PARAMETER _peak; explicit EVAL_BM_SFFM(const EVAL_BM_SFFM& p); public: explicit EVAL_BM_SFFM(int c=0); ~EVAL_BM_SFFM() {} private: // override vitrual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_SFFM(*this);} void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void precalc_first(const CARD_LIST*); void tr_eval(ELEMENT*)const; TIME_PAIR tr_review(COMPONENT*); std::string name()const {return "sffm";} bool ac_too()const {return false;} bool parse_numlist(CS&); bool parse_params_obsolete_callback(CS&); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_SFFM::EVAL_BM_SFFM(int c) :EVAL_BM_ACTION_BASE(c), _offset(_default_offset), _amplitude(_default_amplitude), _carrier(_default_carrier), _modindex(_default_modindex), _signal(_default_signal), _end(NOT_VALID), _samples(_default_samples), _zero(_default_zero), _peak(_default_peak) { } /*--------------------------------------------------------------------------*/ EVAL_BM_SFFM::EVAL_BM_SFFM(const EVAL_BM_SFFM& p) :EVAL_BM_ACTION_BASE(p), _offset(p._offset), _amplitude(p._amplitude), _carrier(p._carrier), _modindex(p._modindex), _signal(p._signal), _end(NOT_VALID), _samples(p._samples), _zero(p._zero), _peak(p._peak) { } /*--------------------------------------------------------------------------*/ bool EVAL_BM_SFFM::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_SFFM* p = dynamic_cast(&x); bool rv = p && _offset == p->_offset && _amplitude == p->_amplitude && _carrier == p->_carrier && _modindex == p->_modindex && _signal == p->_signal && _samples == p->_samples && _zero == p->_zero && _peak == p->_peak && EVAL_BM_ACTION_BASE::operator==(x); if (rv) { untested(); } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_SFFM::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); o << name(); print_pair(o, lang, "offset", _offset); print_pair(o, lang, "amplitude", _amplitude); print_pair(o, lang, "carrier", _carrier); print_pair(o, lang, "modindex", _modindex); print_pair(o, lang, "signal", _signal); print_pair(o, lang, "samples", _samples, _samples.has_hard_value()); print_pair(o, lang, "zero", _zero, _zero.has_hard_value()); print_pair(o, lang, "peak", _peak, _peak.has_hard_value()); EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ void EVAL_BM_SFFM::precalc_first(const CARD_LIST* Scope) { assert(Scope); EVAL_BM_ACTION_BASE::precalc_first(Scope); _offset.e_val(_default_offset, Scope); _amplitude.e_val(_default_amplitude, Scope); _carrier.e_val(_default_carrier, Scope); _modindex.e_val(_default_modindex, Scope); _signal.e_val(_default_signal, Scope); _samples.e_val(_default_samples, Scope); _zero.e_val(_default_zero, Scope); _peak.e_val(_default_peak, Scope); } /*--------------------------------------------------------------------------*/ void EVAL_BM_SFFM::tr_eval(ELEMENT* d)const { double time = d->_sim->_time0; double mod = (_modindex * sin(M_TWO_PI * _signal * time)); double ev = _offset + _amplitude * sin(M_TWO_PI * _carrier * time + mod); tr_finish_tdv(d, ev); } /*--------------------------------------------------------------------------*/ TIME_PAIR EVAL_BM_SFFM::tr_review(COMPONENT* d) { double time = d->_sim->_time0 + d->_sim->_dtmin * .01; double old_time; double N = 0; double old_N; trace2("", time, N); do { // simple fixed point iteration to find peaks and zero crossings old_time = time; old_N = N; double mod = (_modindex * sin(M_TWO_PI * _signal * time)); double inst_freq = _carrier * (1 + mod / (M_TWO_PI * _carrier * time)); if (N == 0) { if (_peak && _zero) { N = floor(time * 4 * inst_freq + 1); }else if (_peak) {untested(); N = floor(time * 2 * inst_freq + .5) + .5; }else if (_zero) {untested(); N = floor(time * 2 * inst_freq + 1); }else{ N = 0; } }else{ } if (_peak && _zero) { time = N / (4 * inst_freq); }else if (_peak) {untested(); time = N / (2 * inst_freq); }else if (_zero) {untested(); time = N / (2 * inst_freq); }else{ time = NEVER; } trace2("", time, N); } while (std::abs(dn_diff(time, old_time)) > 0); d->_time_by.min_error_estimate(d->_sim->_time0 + 1. / (_samples * _carrier)); d->_time_by.min_event(old_time); return d->_time_by; } /*--------------------------------------------------------------------------*/ bool EVAL_BM_SFFM::parse_numlist(CS& cmd) { unsigned start = cmd.cursor(); unsigned here = cmd.cursor(); for (PARAMETER* i = &_offset; i < &_end; ++i) { PARAMETER val(NOT_VALID); cmd >> val; if (cmd.stuck(&here)) { break; }else{ untested(); *i = val; } } if (cmd.gotit(start)) { untested(); } return cmd.gotit(start); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_SFFM::parse_params_obsolete_callback(CS& cmd) { return ONE_OF || Get(cmd, "offset", &_offset) || Get(cmd, "amplitude", &_amplitude) || Get(cmd, "carrier", &_carrier) || Get(cmd, "modindex", &_modindex) || Get(cmd, "signal", &_signal) || Get(cmd, "samples", &_samples) || Get(cmd, "zero", &_zero) || Get(cmd, "peak", &_peak) || EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd) ; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_SFFM p1(CC_STATIC); DISPATCHER::INSTALL d1(&bm_dispatcher, "sffm", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bm_sin.cc000066400000000000000000000175501145401216200134270ustar00rootroot00000000000000/*$Id: bm_sin.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * SPICE compatible SIN */ //testing=script,complete 2005.10.07 #include "e_elemnt.h" #include "u_lang.h" #include "l_denoise.h" #include "bm.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ const double _default_offset (0); const double _default_amplitude (1); const double _default_frequency (NOT_INPUT); const double _default_delay (0); const double _default_damping (0); const double _default_samples (4); const bool _default_zero (false); const bool _default_peak (false); /*--------------------------------------------------------------------------*/ class EVAL_BM_SIN : public EVAL_BM_ACTION_BASE { private: PARAMETER _offset; PARAMETER _amplitude; PARAMETER _frequency; PARAMETER _delay; PARAMETER _damping; PARAMETER _end; PARAMETER _samples; PARAMETER _zero; PARAMETER _peak; mutable double _actual_frequency; explicit EVAL_BM_SIN(const EVAL_BM_SIN& p); public: explicit EVAL_BM_SIN(int c=0); ~EVAL_BM_SIN() {} private: // override vitrual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_SIN(*this);} void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void precalc_first(const CARD_LIST*); void tr_eval(ELEMENT*)const; TIME_PAIR tr_review(COMPONENT*); std::string name()const {return "sin";} bool ac_too()const {return false;} bool parse_numlist(CS&); bool parse_params_obsolete_callback(CS&); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_SIN::EVAL_BM_SIN(int c) :EVAL_BM_ACTION_BASE(c), _offset(_default_offset), _amplitude(_default_amplitude), _frequency(_default_frequency), _delay(_default_delay), _damping(_default_damping), _end(NOT_VALID), _samples(_default_samples), _zero(_default_zero), _peak(_default_peak), _actual_frequency(0) { } /*--------------------------------------------------------------------------*/ EVAL_BM_SIN::EVAL_BM_SIN(const EVAL_BM_SIN& p) :EVAL_BM_ACTION_BASE(p), _offset(p._offset), _amplitude(p._amplitude), _frequency(p._frequency), _delay(p._delay), _damping(p._damping), _end(NOT_VALID), _samples(p._samples), _zero(p._zero), _peak(p._peak), _actual_frequency(p._actual_frequency) { } /*--------------------------------------------------------------------------*/ bool EVAL_BM_SIN::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_SIN* p = dynamic_cast(&x); bool rv = p && _offset == p->_offset && _amplitude == p->_amplitude && _frequency == p->_frequency && _delay == p->_delay && _damping == p->_damping && _samples == p->_samples && _zero == p->_zero && _peak == p->_peak && EVAL_BM_ACTION_BASE::operator==(x); if (rv) {untested(); }else{ } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_SIN::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); o << name(); print_pair(o, lang, "offset", _offset); print_pair(o, lang, "amplitude", _amplitude); print_pair(o, lang, "frequency", _frequency); print_pair(o, lang, "delay", _delay); print_pair(o, lang, "damping", _damping); print_pair(o, lang, "samples", _samples, _samples.has_hard_value()); print_pair(o, lang, "zero", _zero, _zero.has_hard_value()); print_pair(o, lang, "peak", _peak, _peak.has_hard_value()); EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ void EVAL_BM_SIN::precalc_first(const CARD_LIST* Scope) { assert(Scope); EVAL_BM_ACTION_BASE::precalc_first(Scope); _offset.e_val(_default_offset, Scope); _amplitude.e_val(_default_amplitude, Scope); _frequency.e_val(_default_frequency, Scope); _delay.e_val(_default_delay, Scope); _damping.e_val(_default_damping, Scope); _samples.e_val(_default_samples, Scope); _zero.e_val(_default_zero, Scope); _peak.e_val(_default_peak, Scope); } /*--------------------------------------------------------------------------*/ void EVAL_BM_SIN::tr_eval(ELEMENT* d)const { if (!_frequency.has_hard_value()) { _actual_frequency = d->_sim->_freq; }else{ _actual_frequency = _frequency; } double reltime = ioffset(d->_sim->_time0); double ev = _offset; if (reltime > _delay) { double x=_amplitude*fixzero(sin(M_TWO_PI*_actual_frequency*(reltime-_delay)),1.); if (_damping != 0.) { x *= exp(-(reltime-_delay)*_damping); }else{ } ev += x; }else{ } tr_finish_tdv(d, ev); } /*--------------------------------------------------------------------------*/ TIME_PAIR EVAL_BM_SIN::tr_review(COMPONENT* d) { double reltime = ioffset(d->_sim->_time0) + d->_sim->_dtmin * .01; if (reltime > _delay) { if (_peak && _zero) { d->_time_by.min_event(floor(reltime * 4 * _actual_frequency + 1) / (4 * _actual_frequency)); }else if (_peak) { d->_time_by.min_event((floor(reltime*2*_actual_frequency+.5) + .5) / (2*_actual_frequency)); }else if (_zero) { d->_time_by.min_event(floor(reltime * 2 * _actual_frequency + 1) / (2 * _actual_frequency)); }else{ } d->_time_by.min_error_estimate(d->_sim->_time0 + 1. / (_samples * _actual_frequency)); }else{ d->_time_by.min_event(_delay); } return d->_time_by; } /*--------------------------------------------------------------------------*/ bool EVAL_BM_SIN::parse_numlist(CS& cmd) { unsigned start = cmd.cursor(); unsigned here = cmd.cursor(); for (PARAMETER* i = &_offset; i < &_end; ++i) { PARAMETER val(NOT_VALID); cmd >> val; if (cmd.stuck(&here)) { break; }else{ *i = val; } } return cmd.gotit(start); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_SIN::parse_params_obsolete_callback(CS& cmd) { return ONE_OF || Get(cmd, "o{ffset}", &_offset) || Get(cmd, "a{mplitude}", &_amplitude) || Get(cmd, "f{requency}", &_frequency) || Get(cmd, "de{lay}", &_delay) || Get(cmd, "da{mping}", &_damping) || Get(cmd, "sa{mples}", &_samples) || Get(cmd, "ze{ro}", &_zero) || Get(cmd, "pe{ak}", &_peak) || EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd) ; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_SIN p1(CC_STATIC); DISPATCHER::INSTALL d1(&bm_dispatcher, "sin|sine", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bm_tanh.cc000066400000000000000000000120731145401216200135630ustar00rootroot00000000000000/*$Id: bm_tanh.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * behavioral modeling hyperbolic tangent */ //testing=script 2005.10.07 #include "u_lang.h" #include "e_elemnt.h" #include "bm.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ const double _default_gain (NOT_INPUT); const double _default_limit (NOT_INPUT); /*--------------------------------------------------------------------------*/ class EVAL_BM_TANH : public EVAL_BM_ACTION_BASE { private: PARAMETER _gain; PARAMETER _limit; explicit EVAL_BM_TANH(const EVAL_BM_TANH& p); public: explicit EVAL_BM_TANH(int c=0); ~EVAL_BM_TANH() {} private: // override virtual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_TANH(*this);} void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void precalc_first(const CARD_LIST*); void tr_eval(ELEMENT*)const; std::string name()const {return "tanh";} bool ac_too()const {untested();return false;} bool parse_numlist(CS&); bool parse_params_obsolete_callback(CS&); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_TANH::EVAL_BM_TANH(int c) :EVAL_BM_ACTION_BASE(c), _gain(NOT_INPUT), _limit(NOT_INPUT) { } /*--------------------------------------------------------------------------*/ EVAL_BM_TANH::EVAL_BM_TANH(const EVAL_BM_TANH& p) :EVAL_BM_ACTION_BASE(p), _gain(p._gain), _limit(p._limit) { } /*--------------------------------------------------------------------------*/ bool EVAL_BM_TANH::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_TANH* p = dynamic_cast(&x); bool rv = p && _gain == p->_gain && _limit == p->_limit && EVAL_BM_ACTION_BASE::operator==(x); if (rv) { untested(); } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_TANH::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); o << name(); print_pair(o, lang, "gain", _gain); print_pair(o, lang, "limit", _limit); EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ void EVAL_BM_TANH::precalc_first(const CARD_LIST* Scope) { assert(Scope); EVAL_BM_ACTION_BASE::precalc_first(Scope); _gain.e_val(_default_gain, Scope); _limit.e_val(_default_limit, Scope); } /*--------------------------------------------------------------------------*/ void EVAL_BM_TANH::tr_eval(ELEMENT* d)const { double x = ioffset(d->_y[0].x); double aa = x * _gain/_limit; double f1, f0; if (aa > LOGBIGBIG) { f1 = 0; f0 = _limit; }else if (aa < -LOGBIGBIG) { f1 = 0; f0 = -_limit; }else{ double cosine = cosh(aa); f1 = _gain / (cosine*cosine); f0 = _limit * tanh(aa); } d->_y[0] = FPOLY1(x, f0, f1); tr_final_adjust(&(d->_y[0]), d->f_is_value()); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_TANH::parse_numlist(CS& cmd) { unsigned here = cmd.cursor(); PARAMETER gain(NOT_VALID); PARAMETER limit(NOT_VALID); cmd >> gain >> limit; if (cmd.gotit(here)) { _gain = gain; _limit = limit; return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ bool EVAL_BM_TANH::parse_params_obsolete_callback(CS& cmd) { return ONE_OF || Get(cmd, "gain", &_gain) || Get(cmd, "limit", &_limit) || EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd) ; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ EVAL_BM_TANH p1(CC_STATIC); DISPATCHER::INSTALL d1(&bm_dispatcher, "tanh", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bm_value.cc000066400000000000000000000066441145401216200137540ustar00rootroot00000000000000/*$Id: bm_value.cc,v 26.130 2009/11/15 21:51:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * behavioral modeling simple value * used with tc, etc, and conditionals */ //testing=script 2005.10.07 #include "bm.h" /*--------------------------------------------------------------------------*/ static EVAL_BM_VALUE p1(CC_STATIC); static DISPATCHER::INSTALL d1(&bm_dispatcher, "value|eval_bm_value", &p1); /*--------------------------------------------------------------------------*/ bool EVAL_BM_VALUE::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_VALUE* p = dynamic_cast(&x); return p && EVAL_BM_ACTION_BASE::operator==(x); } /*--------------------------------------------------------------------------*/ void EVAL_BM_VALUE::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { o << _value; EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_VALUE::is_trivial()const { return !(_bandwidth.has_hard_value() || _delay.has_hard_value() || _phase.has_hard_value() || _ooffset.has_hard_value() || _ioffset.has_hard_value() || _scale.has_hard_value() || _tc1.has_hard_value() || _tc2.has_hard_value() || _ic.has_hard_value() || _tnom_c.has_hard_value() || _dtemp.has_hard_value() || _temp_c.has_hard_value()); } /*--------------------------------------------------------------------------*/ void EVAL_BM_VALUE::precalc_first(const CARD_LIST* Scope) { if (modelname() != "") { _value = modelname(); }else{ } EVAL_BM_ACTION_BASE::precalc_first(Scope); } /*--------------------------------------------------------------------------*/ void EVAL_BM_VALUE::tr_eval(ELEMENT* d)const { tr_finish_tdv(d, _value); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_VALUE::parse_numlist(CS& cmd) { unsigned here = cmd.cursor(); PARAMETER new_value(NOT_VALID); cmd >> new_value; if (cmd.gotit(here)) { _value = new_value; return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ bool EVAL_BM_VALUE::parse_params_obsolete_callback(CS& cmd) { return ONE_OF || Get(cmd, "=", &_value) || EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd) ; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bmm_semi.cc000066400000000000000000000471051145401216200137470ustar00rootroot00000000000000/*$Id: bmm_semi.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * behavioral modeling * Spice3 compatible "semiconductor resistor and capacitor" */ //testing=script 2006.07.13 #include "u_lang.h" #include "e_model.h" #include "bm.h" /*--------------------------------------------------------------------------*/ class EVAL_BM_SEMI_BASE : public EVAL_BM_ACTION_BASE { protected: PARAMETER _length; PARAMETER _width; double _value; private: static double const _default_length; static double const _default_width; static double const _default_value; protected: explicit EVAL_BM_SEMI_BASE(const EVAL_BM_SEMI_BASE& p); explicit EVAL_BM_SEMI_BASE(int c=0); ~EVAL_BM_SEMI_BASE() {} protected: // override virtual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const = 0; void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void precalc_first(const CARD_LIST*); void expand(const COMPONENT*); void tr_eval(ELEMENT*)const; std::string name()const {untested();return modelname().c_str();} bool ac_too()const {untested();return false;} bool parse_params_obsolete_callback(CS&); }; /*--------------------------------------------------------------------------*/ class EVAL_BM_SEMI_CAPACITOR : public EVAL_BM_SEMI_BASE { private: explicit EVAL_BM_SEMI_CAPACITOR(const EVAL_BM_SEMI_CAPACITOR& p) :EVAL_BM_SEMI_BASE(p) {} public: explicit EVAL_BM_SEMI_CAPACITOR(int c=0) :EVAL_BM_SEMI_BASE(c) {} ~EVAL_BM_SEMI_CAPACITOR() {} private: // override virtual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_SEMI_CAPACITOR(*this);} void expand(const COMPONENT*); void precalc_last(const CARD_LIST*); }; /*--------------------------------------------------------------------------*/ class EVAL_BM_SEMI_RESISTOR : public EVAL_BM_SEMI_BASE { private: explicit EVAL_BM_SEMI_RESISTOR(const EVAL_BM_SEMI_RESISTOR& p) :EVAL_BM_SEMI_BASE(p) {} public: explicit EVAL_BM_SEMI_RESISTOR(int c=0) :EVAL_BM_SEMI_BASE(c) {} ~EVAL_BM_SEMI_RESISTOR() {} private: // override virtual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_SEMI_RESISTOR(*this);} void expand(const COMPONENT*); void precalc_last(const CARD_LIST*); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ class MODEL_SEMI_BASE : public MODEL_CARD { public: PARAMETER _narrow; PARAMETER _defw; PARAMETER _tc1; PARAMETER _tc2; private: static double const _default_narrow; static double const _default_defw; static double const _default_tc1; static double const _default_tc2; protected: explicit MODEL_SEMI_BASE(); explicit MODEL_SEMI_BASE(const MODEL_SEMI_BASE& p); protected: // override virtual void precalc_first(); //void precalc_last(); //CARD* clone()const //MODEL_CARD/pure void set_param_by_index(int, std::string&, int); bool param_is_printable(int)const; std::string param_name(int)const; std::string param_name(int,int)const; std::string param_value(int)const; int param_count()const {return (4 + MODEL_CARD::param_count());} }; /*--------------------------------------------------------------------------*/ class MODEL_SEMI_CAPACITOR : public MODEL_SEMI_BASE { public: PARAMETER _cj; PARAMETER _cjsw; private: static double const _default_cj; static double const _default_cjsw; private: explicit MODEL_SEMI_CAPACITOR(const MODEL_SEMI_CAPACITOR& p); public: explicit MODEL_SEMI_CAPACITOR(); private: // override virtual std::string dev_type()const {return "c";} void precalc_first(); //void precalc_last(); COMMON_COMPONENT* new_common()const {return new EVAL_BM_SEMI_CAPACITOR;} CARD* clone()const {return new MODEL_SEMI_CAPACITOR(*this);} void set_param_by_index(int, std::string&, int); bool param_is_printable(int)const; std::string param_name(int)const; std::string param_name(int,int)const; std::string param_value(int)const; int param_count()const {return (2 + MODEL_SEMI_BASE::param_count());} }; /*--------------------------------------------------------------------------*/ class MODEL_SEMI_RESISTOR : public MODEL_SEMI_BASE { public: PARAMETER _rsh; private: static double const _default_rsh; private: explicit MODEL_SEMI_RESISTOR(const MODEL_SEMI_RESISTOR& p); public: explicit MODEL_SEMI_RESISTOR(); private: // override virtual std::string dev_type()const {return "r";} void precalc_first(); //void precalc_last(); COMMON_COMPONENT* new_common()const {return new EVAL_BM_SEMI_RESISTOR;} CARD* clone()const {return new MODEL_SEMI_RESISTOR(*this);} void set_param_by_index(int, std::string&, int); bool param_is_printable(int)const; std::string param_name(int)const; std::string param_name(int,int)const; std::string param_value(int)const; int param_count()const {return (1 + MODEL_SEMI_BASE::param_count());} }; /*--------------------------------------------------------------------------*/ double const EVAL_BM_SEMI_BASE::_default_length = NOT_INPUT; double const EVAL_BM_SEMI_BASE::_default_width = NOT_INPUT; double const EVAL_BM_SEMI_BASE::_default_value = NOT_INPUT; /*--------------------------------------------------------------------------*/ static MODEL_SEMI_RESISTOR p1; static MODEL_SEMI_CAPACITOR p2; static DISPATCHER::INSTALL d1(&model_dispatcher, "r|res", &p1), d2(&model_dispatcher, "c|cap", &p2); /*--------------------------------------------------------------------------*/ EVAL_BM_SEMI_BASE::EVAL_BM_SEMI_BASE(int c) :EVAL_BM_ACTION_BASE(c), _length(_default_length), _width(_default_width), _value(_default_value) { } /*--------------------------------------------------------------------------*/ EVAL_BM_SEMI_BASE::EVAL_BM_SEMI_BASE(const EVAL_BM_SEMI_BASE& p) :EVAL_BM_ACTION_BASE(p), _length(p._length), _width(p._width), _value(p._value) { } /*--------------------------------------------------------------------------*/ bool EVAL_BM_SEMI_BASE::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_SEMI_BASE* p = dynamic_cast(&x); bool rv = p && _length == p->_length && _width == p->_width && EVAL_BM_ACTION_BASE::operator==(x); if (rv) { untested(); }else{ } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_SEMI_BASE::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); o << modelname(); print_pair(o, lang, "l", _length); print_pair(o, lang, "w", _width, _width.has_hard_value()); EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ void EVAL_BM_SEMI_BASE::expand(const COMPONENT* d) { EVAL_BM_ACTION_BASE::expand(d); attach_model(d); } /*--------------------------------------------------------------------------*/ void EVAL_BM_SEMI_BASE::precalc_first(const CARD_LIST* Scope) { assert(Scope); EVAL_BM_ACTION_BASE::precalc_first(Scope); _length.e_val(_default_length, Scope); _width.e_val(_default_width, Scope); } /*--------------------------------------------------------------------------*/ void EVAL_BM_SEMI_BASE::tr_eval(ELEMENT* d)const { tr_finish_tdv(d, _value); } /*--------------------------------------------------------------------------*/ bool EVAL_BM_SEMI_BASE::parse_params_obsolete_callback(CS& cmd) { return ONE_OF || Get(cmd, "l", &_length) || Get(cmd, "w", &_width) || EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd) ; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ bool EVAL_BM_SEMI_CAPACITOR::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_SEMI_CAPACITOR* p = dynamic_cast(&x); bool rv = p && EVAL_BM_SEMI_BASE::operator==(x); if (rv) { untested(); }else{ } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_SEMI_CAPACITOR::expand(const COMPONENT* d) { EVAL_BM_SEMI_BASE::expand(d); const MODEL_SEMI_CAPACITOR* m = dynamic_cast(model()); if (!m) { unreachable(); throw Exception_Model_Type_Mismatch(d->long_label(), modelname(), "semi-capacitor (C)"); }else{ } } /*--------------------------------------------------------------------------*/ void EVAL_BM_SEMI_CAPACITOR::precalc_last(const CARD_LIST* Scope) { assert(Scope); EVAL_BM_SEMI_BASE::precalc_last(Scope); const MODEL_SEMI_CAPACITOR* m = prechecked_cast(model()); double width = (_width == NOT_INPUT) ? m->_defw : _width; double eff_width = width - m->_narrow; double eff_length = _length - m->_narrow; _value = m->_cj * eff_length * eff_width + 2. * m->_cjsw * (eff_length + eff_width); double tempdiff = (_temp_c - m->_tnom_c); _value *= 1 + m->_tc1*tempdiff + m->_tc2*tempdiff*tempdiff; if (eff_width <= 0.) {untested(); throw Exception_Precalc(modelname() + ": effective width is negative or zero\n"); }else{ } if (eff_length <= 0.) {untested(); throw Exception_Precalc(modelname() + ": effective length is negative or zero\n"); }else{ } } /*--------------------------------------------------------------------------*/ bool EVAL_BM_SEMI_RESISTOR::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_SEMI_RESISTOR* p = dynamic_cast(&x); bool rv = p && EVAL_BM_SEMI_BASE::operator==(x); if (rv) { untested(); }else{ } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_SEMI_RESISTOR::expand(const COMPONENT* d) { EVAL_BM_SEMI_BASE::expand(d); const MODEL_SEMI_RESISTOR* m = dynamic_cast(model()); if (!m) { unreachable(); throw Exception_Model_Type_Mismatch(d->long_label(), modelname(), "semi-resistor (R)"); }else{ } } /*--------------------------------------------------------------------------*/ void EVAL_BM_SEMI_RESISTOR::precalc_last(const CARD_LIST* Scope) { assert(Scope); EVAL_BM_SEMI_BASE::precalc_last(Scope); const MODEL_SEMI_RESISTOR* m = prechecked_cast(model()); double width = (_width == NOT_INPUT) ? m->_defw : _width; double eff_width = width - m->_narrow; double eff_length = _length - m->_narrow; if (eff_width != 0.) { _value = m->_rsh * eff_length / eff_width; }else{untested(); _value = BIGBIG; } double tempdiff = (_temp_c - m->_tnom_c); _value *= 1 + m->_tc1*tempdiff + m->_tc2*tempdiff*tempdiff; if (eff_width <= 0.) {untested(); throw Exception_Precalc(modelname() + ": effective width is negative or zero\n"); }else{ } if (eff_length <= 0.) { throw Exception_Precalc(modelname() + ": effective length is negative or zero\n"); }else{ } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ double const MODEL_SEMI_BASE::_default_narrow = 0.; double const MODEL_SEMI_BASE::_default_defw = 1e-6; double const MODEL_SEMI_BASE::_default_tc1 = 0.; double const MODEL_SEMI_BASE::_default_tc2 = 0.; /*--------------------------------------------------------------------------*/ MODEL_SEMI_BASE::MODEL_SEMI_BASE() :MODEL_CARD(NULL), _narrow(_default_narrow), _defw(_default_defw), _tc1(_default_tc1), _tc2(_default_tc2) { } /*--------------------------------------------------------------------------*/ MODEL_SEMI_BASE::MODEL_SEMI_BASE(const MODEL_SEMI_BASE& p) :MODEL_CARD(p), _narrow(p._narrow), _defw(p._defw), _tc1(p._tc1), _tc2(p._tc2) { } /*--------------------------------------------------------------------------*/ void MODEL_SEMI_BASE::set_param_by_index(int i, std::string& value, int offset) { switch (MODEL_SEMI_BASE::param_count() - 1 - i) { case 0: _narrow = value; break; case 1: _defw = value; break; case 2: _tc1 = value; break; case 3: _tc2 = value; break; default: MODEL_CARD::set_param_by_index(i, value, offset); break; } } /*--------------------------------------------------------------------------*/ bool MODEL_SEMI_BASE::param_is_printable(int i)const { switch (MODEL_SEMI_BASE::param_count() - 1 - i) { case 0: case 1: case 2: case 3: return true; default: return MODEL_CARD::param_is_printable(i); } } /*--------------------------------------------------------------------------*/ std::string MODEL_SEMI_BASE::param_name(int i)const { switch (MODEL_SEMI_BASE::param_count() - 1 - i) { case 0: return "narrow"; case 1: return "defw"; case 2: return "tc1"; case 3: return "tc2"; default: return MODEL_CARD::param_name(i); } } /*--------------------------------------------------------------------------*/ std::string MODEL_SEMI_BASE::param_name(int i, int j)const { if (j == 0) {untested(); return param_name(i); }else if (i >= MODEL_CARD::param_count()) { return ""; }else{ return MODEL_CARD::param_name(i, j); } } /*--------------------------------------------------------------------------*/ std::string MODEL_SEMI_BASE::param_value(int i)const { switch (MODEL_SEMI_BASE::param_count() - 1 - i) { case 0: return _narrow.string(); case 1: return _defw.string(); case 2: return _tc1.string(); case 3: return _tc2.string(); default: return MODEL_CARD::param_value(i); } } /*--------------------------------------------------------------------------*/ void MODEL_SEMI_BASE::precalc_first() { MODEL_CARD::precalc_first(); const CARD_LIST* s = scope(); assert(s); _narrow.e_val(_default_narrow, s); _defw.e_val(_default_defw, s); _tc1.e_val(_default_tc1, s); _tc2.e_val(_default_tc2, s); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ double const MODEL_SEMI_CAPACITOR::_default_cj = 0.; double const MODEL_SEMI_CAPACITOR::_default_cjsw = 0.; /*--------------------------------------------------------------------------*/ MODEL_SEMI_CAPACITOR::MODEL_SEMI_CAPACITOR() :MODEL_SEMI_BASE(), _cj(_default_cj), _cjsw(_default_cjsw) { } /*--------------------------------------------------------------------------*/ MODEL_SEMI_CAPACITOR::MODEL_SEMI_CAPACITOR(const MODEL_SEMI_CAPACITOR& p) :MODEL_SEMI_BASE(p), _cj(p._cj), _cjsw(p._cjsw) { } /*--------------------------------------------------------------------------*/ void MODEL_SEMI_CAPACITOR::set_param_by_index(int i, std::string& value, int offset) { switch (MODEL_SEMI_CAPACITOR::param_count() - 1 - i) { case 0: _cj = value; break; case 1: _cjsw = value; break; default: MODEL_SEMI_BASE::set_param_by_index(i, value, offset); break; } } /*--------------------------------------------------------------------------*/ bool MODEL_SEMI_CAPACITOR::param_is_printable(int i)const { switch (MODEL_SEMI_CAPACITOR::param_count() - 1 - i) { case 0: case 1: return true; default: return MODEL_SEMI_BASE::param_is_printable(i); } } /*--------------------------------------------------------------------------*/ std::string MODEL_SEMI_CAPACITOR::param_name(int i)const { switch (MODEL_SEMI_CAPACITOR::param_count() - 1 - i) { case 0: return "cj"; case 1: return "cjsw"; default: return MODEL_SEMI_BASE::param_name(i); } } /*--------------------------------------------------------------------------*/ std::string MODEL_SEMI_CAPACITOR::param_name(int i, int j)const { if (j == 0) { return param_name(i); }else if (i >= MODEL_SEMI_BASE::param_count()) { return ""; }else{ return MODEL_SEMI_BASE::param_name(i, j); } } /*--------------------------------------------------------------------------*/ std::string MODEL_SEMI_CAPACITOR::param_value(int i)const { switch (MODEL_SEMI_CAPACITOR::param_count() - 1 - i) { case 0: return _cj.string(); case 1: return _cjsw.string(); default: return MODEL_SEMI_BASE::param_value(i); } } /*--------------------------------------------------------------------------*/ void MODEL_SEMI_CAPACITOR::precalc_first() { MODEL_SEMI_BASE::precalc_first(); const CARD_LIST* s = scope(); assert(s); _cj.e_val(_default_cj, s); _cjsw.e_val(_default_cjsw, s); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ double const MODEL_SEMI_RESISTOR::_default_rsh = NOT_INPUT; /*--------------------------------------------------------------------------*/ MODEL_SEMI_RESISTOR::MODEL_SEMI_RESISTOR() :MODEL_SEMI_BASE(), _rsh(_default_rsh) { } /*--------------------------------------------------------------------------*/ MODEL_SEMI_RESISTOR::MODEL_SEMI_RESISTOR(const MODEL_SEMI_RESISTOR& p) :MODEL_SEMI_BASE(), _rsh(p._rsh) { } /*--------------------------------------------------------------------------*/ void MODEL_SEMI_RESISTOR::set_param_by_index(int i, std::string& value, int offset) { switch (MODEL_SEMI_RESISTOR::param_count() - 1 - i) { case 0: _rsh = value; break; default: MODEL_SEMI_BASE::set_param_by_index(i, value, offset); break; } } /*--------------------------------------------------------------------------*/ bool MODEL_SEMI_RESISTOR::param_is_printable(int i)const { switch (MODEL_SEMI_RESISTOR::param_count() - 1 - i) { case 0: return true; default: return MODEL_SEMI_BASE::param_is_printable(i); } } /*--------------------------------------------------------------------------*/ std::string MODEL_SEMI_RESISTOR::param_name(int i)const { switch (MODEL_SEMI_RESISTOR::param_count() - 1 - i) { case 0: return "rsh"; default: return MODEL_SEMI_BASE::param_name(i); } } /*--------------------------------------------------------------------------*/ std::string MODEL_SEMI_RESISTOR::param_name(int i, int j)const { if (j == 0) { return param_name(i); }else if (i >= MODEL_SEMI_BASE::param_count()) { return ""; }else{ return MODEL_SEMI_BASE::param_name(i, j); } } /*--------------------------------------------------------------------------*/ std::string MODEL_SEMI_RESISTOR::param_value(int i)const { switch (MODEL_SEMI_RESISTOR::param_count() - 1 - i) { case 0: return _rsh.string(); default: return MODEL_SEMI_BASE::param_value(i); } } /*--------------------------------------------------------------------------*/ void MODEL_SEMI_RESISTOR::precalc_first() { MODEL_SEMI_BASE::precalc_first(); const CARD_LIST* par_scope = scope(); assert(par_scope); _rsh.e_val(_default_rsh, par_scope); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/bmm_table.cc000066400000000000000000000204331145401216200140740ustar00rootroot00000000000000/*$Id: bmm_table.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * behavioral modeling * table as a .model card */ //testing=script 2006.04.18 #include "u_lang.h" #include "e_elemnt.h" #include "m_spline.h" #include "e_model.h" #include "bm.h" /*--------------------------------------------------------------------------*/ class SPLINE; /*--------------------------------------------------------------------------*/ class EVAL_BM_TABLE : public EVAL_BM_ACTION_BASE { protected: explicit EVAL_BM_TABLE(const EVAL_BM_TABLE& p); public: explicit EVAL_BM_TABLE(int c=0); ~EVAL_BM_TABLE() {} private: // override virtual bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new EVAL_BM_TABLE(*this);} void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void expand(const COMPONENT*); void tr_eval(ELEMENT*)const; std::string name()const {untested();return modelname().c_str();} bool ac_too()const {untested();return false;} }; /*--------------------------------------------------------------------------*/ class MODEL_TABLE : public MODEL_CARD { public: PARAMETER _order; PARAMETER _below; PARAMETER _above; std::vector,PARAMETER > > _table; SPLINE* _spline; private: static int const _default_order; static double const _default_below; static double const _default_above; private: explicit MODEL_TABLE(const MODEL_TABLE& p); public: explicit MODEL_TABLE(); ~MODEL_TABLE(); private: // override virtual std::string dev_type()const {return "table";} void precalc_first(); COMMON_COMPONENT* new_common()const {return new EVAL_BM_TABLE;} CARD* clone()const {return new MODEL_TABLE(*this);} bool use_obsolete_callback_print()const {return true;} bool use_obsolete_callback_parse()const {return true;} void print_args_obsolete_callback(OMSTREAM&,LANGUAGE*)const; bool parse_params_obsolete_callback(CS&); void tr_eval(COMPONENT*)const; }; /*--------------------------------------------------------------------------*/ int const MODEL_TABLE::_default_order = 3; double const MODEL_TABLE::_default_below = NOT_INPUT; double const MODEL_TABLE::_default_above = NOT_INPUT; /*--------------------------------------------------------------------------*/ static MODEL_TABLE p1; static DISPATCHER::INSTALL d1(&model_dispatcher, "table", &p1); /*--------------------------------------------------------------------------*/ EVAL_BM_TABLE::EVAL_BM_TABLE(int c) :EVAL_BM_ACTION_BASE(c) { } /*--------------------------------------------------------------------------*/ EVAL_BM_TABLE::EVAL_BM_TABLE(const EVAL_BM_TABLE& p) :EVAL_BM_ACTION_BASE(p) { } /*--------------------------------------------------------------------------*/ bool EVAL_BM_TABLE::operator==(const COMMON_COMPONENT& x)const { const EVAL_BM_TABLE* p = dynamic_cast(&x); bool rv = p && EVAL_BM_ACTION_BASE::operator==(x); if (rv) { untested(); }else{ } return rv; } /*--------------------------------------------------------------------------*/ void EVAL_BM_TABLE::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); o << modelname(); EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ void EVAL_BM_TABLE::expand(const COMPONENT* d) { EVAL_BM_ACTION_BASE::expand(d); attach_model(d); const MODEL_TABLE* m = dynamic_cast(model()); if (!m) {untested(); throw Exception_Model_Type_Mismatch(d->long_label(), modelname(), "table"); }else{ } } /*--------------------------------------------------------------------------*/ void EVAL_BM_TABLE::tr_eval(ELEMENT* d)const { model()->tr_eval(d); tr_final_adjust(&(d->_y[0]), d->f_is_value()); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ MODEL_TABLE::MODEL_TABLE() :MODEL_CARD(NULL), _order(_default_order), _below(_default_below), _above(_default_above), _table(), _spline(0) { } /*--------------------------------------------------------------------------*/ MODEL_TABLE::MODEL_TABLE(const MODEL_TABLE& p) :MODEL_CARD(p), _order(p._order), _below(p._below), _above(p._above), _table(p._table), _spline(p._spline) { } /*--------------------------------------------------------------------------*/ MODEL_TABLE::~MODEL_TABLE() { delete _spline; } /*--------------------------------------------------------------------------*/ bool MODEL_TABLE::parse_params_obsolete_callback(CS& cmd) { unsigned here1 = cmd.cursor(); { Get(cmd, "order", &_order); Get(cmd, "below", &_below); Get(cmd, "above", &_above); bool got_opening_paren = cmd.skip1b('('); unsigned here = cmd.cursor(); for (;;) { unsigned start_of_pair = here; std::pair, PARAMETER > p; cmd >> p.first; // key if (cmd.stuck(&here)) { break; }else{ cmd >> p.second; // value if (cmd.stuck(&here)) { cmd.reset(start_of_pair); break; }else{ _table.push_back(p); } } } if (got_opening_paren && !cmd.skip1b(')')) { untested(); cmd.warn(bWARNING, "need )"); }else if (!got_opening_paren && cmd.skip1b(')')) { untested(); cmd.warn(bWARNING, here, "need ("); } } return !(cmd.stuck(&here1)); } /*--------------------------------------------------------------------------*/ void MODEL_TABLE::print_args_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); print_pair(o, lang, "order", _order); print_pair(o, lang, "below", _below, _below.has_hard_value()); print_pair(o, lang, "above", _above, _above.has_hard_value()); o << " ("; for (std::vector,PARAMETER > >:: const_iterator p = _table.begin(); p != _table.end(); ++p) { o << p->first << ',' << p->second << ' '; } o << ')'; } /*--------------------------------------------------------------------------*/ void MODEL_TABLE::precalc_first() { MODEL_CARD::precalc_first(); const CARD_LIST* par_scope = scope(); assert(par_scope); _order.e_val(_default_order, par_scope); _below.e_val(_default_below, par_scope); _above.e_val(_default_above, par_scope); { double last = -BIGBIG; for (std::vector,PARAMETER > >:: iterator p = _table.begin(); p != _table.end(); ++p) { p->first.e_val(0, par_scope); p->second.e_val(0, par_scope); if (last > p->first) { untested(); error(bWARNING, "%s: table is out of order: (%g, %g)\n", long_label().c_str(), last, double(p->first)); }else{ //std::pair x(p->first, p->second); //_num_table.push_back(x); } last = p->first; } } delete _spline; double below = _below.has_hard_value() ? _below : NOT_INPUT; double above = _above.has_hard_value() ? _above : NOT_INPUT; _spline = new SPLINE(_table, below, above, _order); } /*--------------------------------------------------------------------------*/ void MODEL_TABLE::tr_eval(COMPONENT* brh)const { ELEMENT* d = prechecked_cast(brh); assert(d); d->_y[0] = _spline->at(d->_y[0].x); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c__cmd.cc000066400000000000000000000103401145401216200133520ustar00rootroot00000000000000/*$Id: c__cmd.cc,v 26.130 2009/11/15 21:51:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * command interpreter and dispatcher */ //testing=obsolete #include "u_status.h" #include "declare.h" /* plclose */ #include "c_comand.h" #include "globals.h" /*--------------------------------------------------------------------------*/ /* cmdproc: process a command * parse, and act on, a command string */ void CMD::cmdproc(CS& cmd, CARD_LIST* scope) { bool get_timer_was_running = ::status.get.is_running(); ::status.get.stop(); static TIMER timecheck; bool didsomething = true; error(bTRACE, ">>>>>" + cmd.fullstring() + "\n"); timecheck.stop().reset().start(); cmd.umatch(ANTI_COMMENT); while (cmd.umatch(I_PROMPT)) {itested(); /* skip any number of these */ } unsigned here = cmd.cursor(); std::string s; // Map possible short names to full ones. // If this if/else block is removed, the only loss is the short names. // Although it looks like it can be used to make aliases, don't. if (cmd.umatch("'|*|#|//|\"")) {itested(); s = "xxxxcomment";} else if (cmd.umatch("b{uild} ")) {itested(); s = "build";} else if (cmd.umatch("del{ete} ")) { s = "delete";} else if (cmd.umatch("fo{urier} ")) { s = "fourier";} else if (cmd.umatch("gen{erator} ")) { s = "generator";} else if (cmd.umatch("inc{lude} ")) {itested(); s = "include";} else if (cmd.umatch("l{ist} ")) { s = "list";} else if (cmd.umatch("m{odify} ")) { s = "modify";} else if (cmd.umatch("opt{ions} ")) { s = "options";} else if (cmd.umatch("par{ameter} ")) { s = "param";} else if (cmd.umatch("pr{int} ")) { s = "print";} else if (cmd.umatch("q{uit} ")) { s = "quit";} else if (cmd.umatch("st{atus} ")) { s = "status";} else if (cmd.umatch("te{mperature} ")){itested(); s = "temperature";} else if (cmd.umatch("tr{ansient} ")) { s = "transient";} else if (cmd.umatch("!")) { s = "system";} else if (cmd.umatch("<")) {untested(); s = "<";} else if (cmd.umatch(">")) {untested(); s = ">";} else{ /* no shortcut available */ cmd >> s; didsomething = false; } if (s == "xxxxcomment") {itested(); // nothing }else if (s != "") { CMD* c = command_dispatcher[s]; if (c) { c->do_it(cmd, scope); didsomething = true; }else{itested(); cmd.warn(bWARNING, here, "what's this?"); } }else if (!didsomething) {itested(); cmd.check(bWARNING, "bad command"); didsomething = false; }else{itested(); } if (OPT::acct && didsomething) {itested(); IO::mstdout.form("time=%8.2f\n", timecheck.check().elapsed()); }else{ } plclose(); outreset(); if (get_timer_was_running) { ::status.get.start(); }else{ } } /*--------------------------------------------------------------------------*/ void CMD::command(const std::string& cs, CARD_LIST* scope) { CS cmd(CS::_STRING, cs); // from string, full command std::string s; cmd >> s; CMD* c = command_dispatcher[s]; if (c) { c->do_it(cmd, scope); }else{itested(); throw Exception("bad internal command: " + s); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_attach.cc000066400000000000000000000073131145401216200137220ustar00rootroot00000000000000/*$Id: c_attach.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2007 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ //testing=informal #include "e_cardlist.h" #include "c_comand.h" #include "globals.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ std::map attach_list; /*--------------------------------------------------------------------------*/ class CMD_ATTACH : public CMD { public: void do_it(CS& cmd, CARD_LIST*) { unsigned here = cmd.cursor(); int dl_scope = RTLD_LOCAL; int check = RTLD_NOW; // RTLD_NOW means to resolve symbols on loading // RTLD_LOCAL means symbols defined in a plugin are local do { if (cmd.umatch("public ")) { dl_scope = RTLD_GLOBAL; // RTLD_GLOBAL means symbols defined in a plugin are global // Use this when a plugin depends on another. }else if (cmd.umatch("lazy ")) { check = RTLD_LAZY; // RTLD_LAZY means to defer resolving symbols until needed // Use when a plugin will not load because of unresolved symbols, // but it may work without it. }else{ } } while (cmd.more() && !cmd.stuck(&here)); std::string file_name; cmd >> file_name; void* handle = attach_list[file_name]; if (handle) { if (CARD_LIST::card_list.is_empty()) { cmd.warn(bDANGER, here, "\"" + file_name + "\": already loaded, replacing"); dlclose(handle); attach_list[file_name] = NULL; }else{untested(); cmd.reset(here); throw Exception_CS("already loaded, cannot replace when there is a circuit", cmd); } }else{ } handle = dlopen(file_name.c_str(), check | dl_scope); if (handle) { attach_list[file_name] = handle; }else{itested(); cmd.reset(here); throw Exception_CS(dlerror(), cmd); } } } p1; DISPATCHER::INSTALL d1(&command_dispatcher, "attach|load", &p1); /*--------------------------------------------------------------------------*/ class CMD_DETACH : public CMD { public: void do_it(CS& cmd, CARD_LIST*) { if (CARD_LIST::card_list.is_empty()) { unsigned here = cmd.cursor(); std::string file_name; cmd >> file_name; void* handle = attach_list[file_name]; if (handle) { dlclose(handle); attach_list[file_name] = NULL; }else{itested(); cmd.reset(here); throw Exception_CS("plugin not attached", cmd); } }else{itested(); throw Exception_CS("detach prohibited when there is a circuit", cmd); } } } p2; DISPATCHER::INSTALL d2(&command_dispatcher, "detach|unload", &p2); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_clear.cc000066400000000000000000000040641145401216200135440ustar00rootroot00000000000000/*$Id: c_clear.cc,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2007 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * delete and clear commands */ //testing=script,complete 2006.07.16 #include "c_comand.h" #include "globals.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ /* cmd_clear: clear the whole circuit, including faults, etc * equivalent to unfault; unkeep; delete all; title = (blank) */ class CMD_CLEAR : public CMD { public: void do_it(CS&, CARD_LIST* Scope) { command("unfault", Scope); command("unmark", Scope); //command("ic clear", Scope); //command("nodeset clear", Scope); command("alarm clear", Scope); command("plot clear", Scope); command("print clear", Scope); command("delete all", Scope); command("title '", Scope); } } p0; DISPATCHER::INSTALL d0(&command_dispatcher, "clear", &p0); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_comand.cc000066400000000000000000000104621145401216200137160ustar00rootroot00000000000000/*$Id: c_comand.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * simple commands and stubs for the missing commands */ //testing=script,sparse 2006.07.16 #include "constant.h" #include "c_comand.h" #include "globals.h" /*--------------------------------------------------------------------------*/ extern std::string head; /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class CMD_OPT : public CMD { public: void do_it(CS& cmd, CARD_LIST*) { static OPT o; o.command(cmd); } } p5; DISPATCHER::INSTALL d5(&command_dispatcher, "options|set|width", &p5); /*--------------------------------------------------------------------------*/ class CMD_END : public CMD { public: void do_it(CS&, CARD_LIST* Scope) { switch (ENV::run_mode) { case rPRE_MAIN: unreachable(); break; case rPRESET: untested(); break; //BUG// this should close the file case rINTERACTIVE: itested(); command("quit", Scope); break; case rSCRIPT: if (OPT::acct) {untested(); command("status", Scope); }else{untested(); } untested(); throw Exception("end"); break; case rBATCH: if (OPT::acct) {itested(); command("status", Scope); }else{ } command("quit", Scope); break; } } } p0; DISPATCHER::INSTALL d0(&command_dispatcher, "end", &p0); /*--------------------------------------------------------------------------*/ class CMD_PAUSE : public CMD { public: void do_it(CS&, CARD_LIST*) {untested(); //BUG// buffer problem //BUG// redirection problem IO::error << "Continue? "; int ch = getchar(); if (ch=='n' || ch=='N' || ch=='C'-'@' || ch=='['-'@') {untested(); throw Exception("pause-stop"); }else{untested(); } } } p1; DISPATCHER::INSTALL d1(&command_dispatcher, "pause", &p1); /*--------------------------------------------------------------------------*/ class CMD_QUIT : public CMD { public: void do_it(CS&, CARD_LIST* Scope) { switch (ENV::run_mode) { case rPRE_MAIN: unreachable(); break; case rINTERACTIVE: itested(); case rSCRIPT: case rBATCH: command("clear", Scope); exit(0); break; case rPRESET: untested(); /*nothing*/ break; } } } p2; DISPATCHER::INSTALL d2(&command_dispatcher, "quit|exit", &p2); /*--------------------------------------------------------------------------*/ class CMD_TEMP : public CMD { public: void do_it(CS& cmd, CARD_LIST*) {itested(); double t = NOT_INPUT; unsigned here = cmd.cursor(); cmd >> '=' >> t; if (!cmd.stuck(&here)) {itested(); OPT::temp_c = t; }else{itested(); IO::mstdout << ".temp = " << OPT::temp_c << '\n'; } } } p3; DISPATCHER::INSTALL d3(&command_dispatcher, "temperature|temp", &p3); /*--------------------------------------------------------------------------*/ class CMD_TITLE : public CMD { public: void do_it(CS& cmd, CARD_LIST*) { if (cmd.more()) { head = cmd.tail(); }else{itested(); IO::mstdout << head << '\n'; } } } p4; DISPATCHER::INSTALL d4(&command_dispatcher, "title", &p4); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_comand.h000066400000000000000000000032341145401216200135570ustar00rootroot00000000000000/*$Id: c_comand.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * all of the commands */ //testing=trivial 2006.07.17 #ifndef C_COMAND_H #define C_COMAND_H #include "e_card.h" /*--------------------------------------------------------------------------*/ class CS; /*--------------------------------------------------------------------------*/ class INTERFACE CMD : public CARD { public: std::string value_name()const {return "";} virtual void do_it(CS&, CARD_LIST*) = 0; virtual ~CMD() {} static void cmdproc(CS&, CARD_LIST*); static void command(const std::string&, CARD_LIST*); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif src/c_delete.cc000066400000000000000000000102711145401216200137150ustar00rootroot00000000000000/*$Id: c_delete.cc,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * delete and clear commands */ //testing=script,complete 2006.07.16 //BUG// If someone deletes an element inside an instance of a subckt // (like ".delete r1.x1", there is no error message, and the deleted // element will reappear next time an elaboration occurs, which is // usually before anything else. #include "d_subckt.h" #include "c_comand.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class CMD_DELETE : public CMD { private: bool delete_one_name(const std::string& name, CARD_LIST* Scope)const { assert(Scope); std::string::size_type dotplace = name.find_first_of("."); if (dotplace != std::string::npos) { // has a dot, look deeper // Split the name into two parts: // "container" -- where to look (all following the dot) // "dev_name" -- what to look for (all before the dot) std::string dev_name = name.substr(dotplace+1, std::string::npos); std::string container = name.substr(0, dotplace); // container name must be exact match CARD_LIST::iterator i = Scope->find_(container); if (i == Scope->end()) { // can't find "container" (probably .subckt) - no match // try reverse dotplace = name.find_last_of("."); container = name.substr(dotplace+1, std::string::npos); dev_name = name.substr(0, dotplace); // container name must be exact match i = Scope->find_(container); }else{ } if (i == Scope->end()) { // can't find "container" (probably .subckt) - no match return false; }else if (!dynamic_cast(*i)) { // found a match, but it isn't a container (subckt) return false; }else{ // found the container, look inside return delete_one_name(dev_name, (**i).subckt()); } unreachable(); }else{ // no dots, look here if (name.find_first_of("*?") != std::string::npos) { // there's a wild card. do linear search for all matches bool didit = false; { CARD_LIST::iterator i = Scope->begin(); while (i != Scope->end()) { CARD_LIST::iterator old_i = i++; // ^^^^^^^^^^^^ move i past the item being deleted if (wmatch((**old_i).short_label(), name)) { Scope->erase(old_i); didit = true; } } } return didit; }else{ // no wild card. fast search for one exact match CARD_LIST::iterator i = Scope->find_(name); if (i != Scope->end()) { Scope->erase(i); return true; }else{ return false; } } unreachable(); } unreachable(); return false; } //----------------------------------- void do_it(CS& cmd, CARD_LIST* Scope) { if (cmd.umatch("all ")) { CARD_LIST::card_list.erase_all(); }else{ while (cmd.more()) { unsigned mark = cmd.cursor(); bool didit = delete_one_name(cmd.ctos(), Scope); if (!didit) { cmd.warn(bWARNING, mark, "no match"); } } } } } p1; DISPATCHER::INSTALL d1(&command_dispatcher, "delete|rm", &p1); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_exp.cc000066400000000000000000000033561145401216200132550ustar00rootroot00000000000000/*$Id: c_exp.cc,v 26.127 2009/11/09 16:06:11 al Exp $ -*- C++ -*- * Copyright (C) 2007 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ //testing=none #include "globals.h" #include "m_expression.h" #include "c_comand.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class CMD_ : public CMD { public: void do_it(CS& cmd, CARD_LIST* Scope) { Expression e(cmd); cmd.check(bDANGER, "syntax error"); Expression r(e, Scope); std::cout << e << '=' << r << '\n'; } } p0; DISPATCHER::INSTALL d0(&command_dispatcher, "exp|eval", &p0); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_file.cc000066400000000000000000000107021145401216200133710ustar00rootroot00000000000000/*$Id: c_file.cc,v 26.86 2008/07/07 22:31:11 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * log and > commands * log == commands log to a file * > == all output to a file (redirect stdout) * bare command closes the file */ //testing=none 2006.07.16 #include "u_lang.h" #include "c_comand.h" #include "globals.h" /*--------------------------------------------------------------------------*/ extern OMSTREAM mout; /* > file bitmap */ extern OMSTREAM mlog; /* log file bitmap */ /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class CMD_INCLUDE : public CMD { public: void do_it(CS& cmd, CARD_LIST* Scope) { unsigned here = cmd.cursor(); try { std::string file_name; cmd >> file_name; CS file(CS::_INC_FILE, file_name); for (;;) { OPT::language->parse_top_item(file, Scope); } }catch (Exception_File_Open& e) { cmd.warn(bDANGER, here, e.message() + '\n'); }catch (Exception_End_Of_Input& e) { // done } } } p0; DISPATCHER::INSTALL d0(&command_dispatcher, "include", &p0); /*--------------------------------------------------------------------------*/ /* cmd_log: "log" command processing * open a file for logging (history) * arg is name of file * no arg closes the one most recently opened * the file will contain a list of commands executed, for use by "<" * multiple files can be open, they are nested, output to all. */ class CMD_LOG : public CMD { public: void do_it(CS& cmd, CARD_LIST*) {itested(); static std::list filestack; if (cmd.more()) { /* a file name .. open it */ const char *access = "w"; while (cmd.match1('>')) { access = "a"; cmd.skip(); cmd.skipbl(); } FILE* newfile = xopen(cmd,"",access); if (newfile) { filestack.push_back(newfile); mlog.attach(newfile); }else{ } }else{ /* empty command -- close a file */ if (filestack.empty()) { error(bWARNING, "no files open\n"); }else{ FILE* oldfile = filestack.back(); filestack.pop_back(); mlog.detach(oldfile); fclose(oldfile); } } } } p1; DISPATCHER::INSTALL d1(&command_dispatcher, "log", &p1); /*--------------------------------------------------------------------------*/ /* cmd_file: ">" command processing * open a file for all output * the file will contain a copy of all screen output. * arg is name of file * no arg closes it * the file will contain all that would go to stdout */ class CMD_FILE : public CMD { public: void do_it(CS& cmd, CARD_LIST*) {itested(); static std::list filestack; if (cmd.more()) { /* a file name .. open it */ const char* access = "w"; while (cmd.match1('>')) { access = "a"; cmd.skip(); cmd.skipbl(); } FILE* newfile = xopen(cmd,"",access); if (newfile) { filestack.push_back(newfile); mout.attach(newfile); IO::mstdout.attach(newfile); }else{ } }else{ /* empty command -- close a file */ if (filestack.empty()) { error(bWARNING, "no files open\n"); }else{ FILE* oldfile = filestack.back(); filestack.pop_back(); mout.detach(oldfile); IO::mstdout.detach(oldfile); fclose(oldfile); } } } } p2; DISPATCHER::INSTALL d2(&command_dispatcher, ">", &p2); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_genrat.cc000066400000000000000000000102331145401216200137310ustar00rootroot00000000000000/*$Id: c_genrat.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * set up generator for transient analysis */ //testing=script,sparse 2006.07.16 #include "u_sim_data.h" #include "globals.h" #include "c_comand.h" /*--------------------------------------------------------------------------*/ static double freq = 0; static double ampl = 1; static double phaz = 0.; static double maxv = 1.; static double minv = 0.; static double offset = 0.; static double init_ = 0.; static double rise = 1e-12; static double fall = 1e-12; static double delay = 0.; static double width = 0.; static double period = 0.; /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class CMD_ : public CMD { public: void do_it(CS& cmd, CARD_LIST*) { OMSTREAM where = (cmd.more()) ? OMSTREAM() : IO::mstdout; unsigned here = cmd.cursor(); do{ ONE_OF || ::Get(cmd, "f{requency}",&freq, mPOSITIVE) || ::Get(cmd, "a{mplitude}",&l) || ::Get(cmd, "p{hase}", &phaz) || ::Get(cmd, "ma{x}", &maxv) || ::Get(cmd, "mi{n}", &minv) || ::Get(cmd, "o{ffset}", &offset) || ::Get(cmd, "i{nitial}", &init_) || ::Get(cmd, "r{ise}", &rise, mPOSITIVE) || ::Get(cmd, "f{all}", &fall, mPOSITIVE) || ::Get(cmd, "d{elay}", &delay, mPOSITIVE) || ::Get(cmd, "w{idth}", &width, mPOSITIVE) || ::Get(cmd, "pe{riod}", &period, mPOSITIVE) ; }while (cmd.more() && !cmd.stuck(&here)); cmd.check(bWARNING, "what's this"); where.setfloatwidth(7); where << "freq=" << freq; where << " ampl=" << ampl; where << " phase=" << phaz; where << " max=" << maxv; where << " min=" << minv; where << " offset="<< offset; where << " init=" << init_; where << " rise=" << rise; where << " fall=" << fall; where << " delay=" << delay; where << " width=" << width; where << " period="<< period; where << "\n"; } } p; DISPATCHER::INSTALL d(&command_dispatcher, "generator", &p); } /*--------------------------------------------------------------------------*/ double gen() { if (CKT_BASE::_sim->_time0 <= delay) { return init_; } double loctime = CKT_BASE::_sim->_time0 - delay; if (period > 0.) { untested(); loctime = fmod(loctime, period); } double level; if (CKT_BASE::_sim->_time0 <= delay + rise) { /* initial rise */ level = (maxv - 0) * (loctime/rise) + 0; }else if (loctime <= rise) { /* rising */ untested(); level = (maxv - minv) * (loctime/rise) + minv; }else if (width==0. || (loctime-=rise) <= width) { /* pulse on */ level = maxv; }else if ((loctime-=width) <= fall) { /* falling */ untested(); level = (minv - maxv) * (loctime/fall) + maxv; }else{ /* pulse off */ untested(); level = minv; } level *= (freq == 0.) ? ampl : ampl * sin(M_TWO_PI * freq*(CKT_BASE::_sim->_time0-delay) + phaz * DTOR); return (CKT_BASE::_sim->_time0 <= delay + rise) ? level + (offset - init_) * (loctime/rise) + init_ : level + offset; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_list.cc000066400000000000000000000100471145401216200134270ustar00rootroot00000000000000/*$Id: c_list.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * list and save commands. * save is list with direction to file */ //testing=script 2006.07.17 #include "e_cardlist.h" #include "u_lang.h" #include "c_comand.h" #include "globals.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ void list_save(CS& cmd, OMSTREAM out, CARD_LIST* scope) { CARD_LIST::card_list.precalc_first(); //out.setfloatwidth(7); switch (ENV::run_mode) { case rPRE_MAIN: unreachable(); return; case rPRESET: /* do nothing */ return; case rBATCH: itested(); case rINTERACTIVE: itested(); case rSCRIPT: /* keep going */ break; } if (!OPT::language) { throw Exception("no language"); }else{ } (out - IO::mstdout) << head << '\n'; if (cmd.is_end()) { /* no args: list all */ for (CARD_LIST::const_iterator ci=scope->begin();ci!=scope->end();++ci) { OPT::language->print_item(out, *ci); } }else{ /* some args: be selective */ unsigned arg1 = cmd.cursor(); CARD_LIST::fat_iterator ci = (cmd.match1('-')) ? CARD_LIST::fat_iterator(scope, scope->begin()) : findbranch(cmd, scope); if (ci.is_end()) {itested(); throw Exception_CS("can't find", cmd); }else{ } if (cmd.match1('-')) { /* there is a dash: a range */ cmd.skip(); if (cmd.is_end()) { /* line ends with dash: all to end */ do { OPT::language->print_item(out, *ci); } while (++ci, !ci.is_end()); }else{ CARD_LIST::fat_iterator stop = ci; stop = findbranch(cmd, ++stop); if (stop.is_end()) {itested(); throw Exception_CS("can't find", cmd); }else{ do { OPT::language->print_item(out, *ci); } while (ci++ != stop); // note subtle difference } } }else{ /* no dash: a list */ do { /* each arg */ unsigned next = cmd.cursor(); do { /* all that match this arg */ OPT::language->print_item(out, *ci); cmd.reset(arg1); assert(!ci.is_end()); ci = findbranch(cmd, ++ci); // next match } while (!ci.is_end()); cmd.reset(arg1 = next); ci = findbranch(cmd, scope); // next arg } while (!ci.is_end()); } } } /*--------------------------------------------------------------------------*/ class CMD_LIST : public CMD { public: void do_it(CS& cmd, CARD_LIST* Scope) { list_save(cmd, IO::mstdout, Scope); } } p1; DISPATCHER::INSTALL d1(&command_dispatcher, "list", &p1); /*--------------------------------------------------------------------------*/ class CMD_SAVE : public CMD { public: void do_it(CS& cmd, CARD_LIST* Scope) {itested(); cmd.reset(); /* back up to beginning of input line */ OMSTREAM out; // = IO::mstdout; list_save(cmd, *outset(cmd,&out), Scope); } } p2; DISPATCHER::INSTALL d2(&command_dispatcher, "save", &p2); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_measure.cc000066400000000000000000000043261145401216200141200ustar00rootroot00000000000000/*$Id: c_measure.cc,v 26.113 2009/08/12 03:37:19 al Exp $ -*- C++ -*- * Copyright (C) 2008 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ //testing=none #include "u_parameter.h" #include "u_function.h" #include "c_comand.h" #include "globals.h" /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class CMD_MEASURE : public CMD { public: void do_it(CS& Cmd, CARD_LIST* Scope) { std::string assign_to, function; Cmd >> assign_to >> '=' >> function >> '('; if (FUNCTION* f = measure_dispatcher[function]) { std::string value = f->eval(Cmd, Scope); if (!Cmd.skip1b(')')) { Cmd.warn(bWARNING, "need )"); }else{ } OMSTREAM out = IO::mstdout; outset(Cmd, &out); out << assign_to << '=' << value << '\n'; PARAM_LIST* pl = Scope->params(); pl->set(assign_to, value); }else{ throw Exception_No_Match(function); } } } p0; DISPATCHER::INSTALL d0(&command_dispatcher, "measure", &p0); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_modify.cc000066400000000000000000000126051145401216200137450ustar00rootroot00000000000000/*$Id: c_modify.cc,v 26.132 2009/11/24 04:26:37 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script,sparse 2006.07.17 #include "e_elemnt.h" #include "u_cardst.h" #include "c_comand.h" extern const int swp_type[]; extern const int swp_count[], swp_steps[]; extern const int swp_nest; /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ enum WHATTODO {FAULT, MODIFY}; std::list faultstack; /*--------------------------------------------------------------------------*/ /* faultbranch: "fault" a single branch. (temporarily change a value) * save the existing info in "faultlist", then patch */ void faultbranch(CARD* brh, double value) { if (!brh->is_device()) { untested(); error(bWARNING, brh->long_label() + ": not a device, can't fault:\n"); }else if (brh->subckt()) { untested(); error(bWARNING, brh->long_label() + " has subckt, can't fault:\n"); }else{ faultstack.push_back(CARDSTASH(brh)); ELEMENT* e = prechecked_cast(brh); assert(e); e->set_value(value, 0); //BUG// messy way to do this, loses other attributes } } /*--------------------------------------------------------------------------*/ /* sweep_fix: fix the value for sweep command. * (find value by interpolation) * if not sweeping, return "start" (the first arg). */ double sweep_fix(CS& cmd, const CARD *brh) { double start = cmd.ctof(); double value = start; if (swp_steps[swp_nest] != 0 && cmd.is_float()) { untested(); double last = cmd.ctof(); double offset = static_cast(swp_count[swp_nest]) / static_cast(swp_steps[swp_nest]); if (swp_type[swp_nest]=='L') { untested(); if (start == 0.) { untested(); throw Exception("log sweep can't pass zero"); value = 0; }else{ untested(); value = start * pow( (last/start), offset ); } }else{ untested(); value = start + (last-start) * offset; } IO::mstdout.setfloatwidth(7) << swp_count[swp_nest]+1 << "> sweep " << brh->long_label() << " =" << value << '\n'; } return value; } /*--------------------------------------------------------------------------*/ void modify_fault(CS& cmd, WHATTODO command, CARD_LIST* scope) { CKT_BASE::_sim->uninit(); while (cmd.is_alpha()) { unsigned mark = cmd.cursor(); unsigned cmax = cmd.cursor(); CARD_LIST::fat_iterator ci(scope, scope->begin()); for (;;) { cmd.reset(mark); ci = findbranch(cmd, ci); cmax = std::max(cmax, cmd.cursor()); if (ci.is_end()) { break; } cmd.skip1b('='); CARD* brh = *ci; switch (command) { case MODIFY:{ ELEMENT* e = prechecked_cast(brh); assert(e); e->set_value(cmd.ctof(), 0); //BUG// messy way to do this, loses other attributes } break; case FAULT:{ faultbranch(brh, sweep_fix(cmd,brh)); } break; } cmax = std::max(cmax, cmd.cursor()); ++ci; } cmd.reset(cmax); if (mark == cmax) { untested(); cmd.check(bWARNING, "what's this?"); cmd.skiparg(); } } } /*--------------------------------------------------------------------------*/ class CMD_MODIFY : public CMD { public: void do_it(CS& cmd, CARD_LIST* Scope) { modify_fault(cmd, MODIFY, Scope); } } p1; DISPATCHER::INSTALL d1(&command_dispatcher, "modify|alter", &p1); /*--------------------------------------------------------------------------*/ class CMD_FAULT : public CMD { public: void do_it(CS& cmd, CARD_LIST* Scope) { modify_fault(cmd, FAULT, Scope); } } p2; DISPATCHER::INSTALL d2(&command_dispatcher, "fault", &p2); /*--------------------------------------------------------------------------*/ class CMD_RESTORE : public CMD { public: void do_it(CS&, CARD_LIST* Scope) {untested(); command("unfault", Scope); command("unmark", Scope); } } p3; DISPATCHER::INSTALL d3(&command_dispatcher, "restore", &p3); /*--------------------------------------------------------------------------*/ class CMD_UNFAULT : public CMD { public: void do_it(CS&, CARD_LIST*) { while (!faultstack.empty()) { faultstack.back().restore(); faultstack.pop_back(); } _sim->uninit(); } } p4; DISPATCHER::INSTALL d4(&command_dispatcher, "unfault", &p4); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_param.cc000066400000000000000000000035031145401216200135530ustar00rootroot00000000000000/*$Id: c_param.cc,v 26.130 2009/11/15 21:51:59 al Exp $ -*- C++ -*- * Copyright (C) 2005 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ //testing=script,complete 2006.07.17 #include "c_comand.h" #include "u_parameter.h" #include "globals.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class CMD_PARAM : public CMD { public: void do_it(CS& cmd, CARD_LIST* Scope) { PARAM_LIST* pl = Scope->params(); if (cmd.is_end()) { pl->print(IO::mstdout, OPT::language); IO::mstdout << '\n'; }else{ pl->parse(cmd); } } } p; DISPATCHER::INSTALL d(&command_dispatcher, "param|parameters|parameter", &p); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_prbcmd.cc000066400000000000000000000116201145401216200137210ustar00rootroot00000000000000/*$Id: c_prbcmd.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * probe and plot commands * set up print and plot (select points, maintain probe lists) * command line operations */ //testing=script,sparse 2006.07.17 #include "u_sim_data.h" #include "c_comand.h" #include "u_prblst.h" #include "globals.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ void do_probe(CS& cmd, PROBELIST *probes) { CKT_BASE::_sim->set_command_none(); enum {aADD, aDELETE, aNEW} action; SIM_MODE simtype = s_NONE; if (cmd.match1('-')) {untested(); /* handle .probe - ac ...... */ action = aDELETE; /* etc. */ cmd.skip(); }else if (cmd.match1('+')) {untested(); action = aADD; cmd.skip(); }else{ /* no -/+ means clear, but wait for */ action = aNEW; /* .probe ac + ..... */ } /* which will not clear first */ ONE_OF || Set(cmd, "tr{ansient}", &simtype, s_TRAN) || Set(cmd, "ac", &simtype, s_AC) || Set(cmd, "dc", &simtype, s_DC) || Set(cmd, "op", &simtype, s_OP) || Set(cmd, "fo{urier}", &simtype, s_FOURIER) ; if (!simtype) { /* must be all simtypes */ if (cmd.is_end()) { /* list all */ probes[s_TRAN].listing("tran"); probes[s_AC].listing("ac"); probes[s_DC].listing("dc"); probes[s_OP].listing("op"); probes[s_FOURIER].listing("fourier"); }else if (cmd.umatch("clear ")) { /* clear all */ for (int ii = sSTART; ii < sCOUNT; ++ii) { probes[ii].clear(); } }else{itested(); /* error */ throw Exception_CS("what's this?", cmd); } }else{ if (cmd.is_end()) {untested(); /* list */ probes[simtype].listing(""); }else if (cmd.umatch("clear ")) {untested();/* clear */ probes[simtype].clear(); }else{ /* add/remove */ CKT_BASE::_sim->init(); if (cmd.match1('-')) {itested(); /* setup cases like: */ action = aDELETE; /* .probe ac + .... */ cmd.skip(); }else if (cmd.match1('+')) { action = aADD; cmd.skip(); }else{ } if (action == aNEW) { /* no +/- here or at beg. */ probes[simtype].clear(); /* means clear first */ action = aADD; }else{ } while (cmd.more()) { /* do-it */ if (cmd.match1('-')) { /* handle cases like: */ action = aDELETE; /* .pr ac +v(7) -e(6) +r(8) */ cmd.skip(); }else if (cmd.match1('+')) {itested(); action = aADD; cmd.skip(); }else{ } if (action == aDELETE) { probes[simtype].remove_list(cmd); }else{ probes[simtype].add_list(cmd); } } } } } /*--------------------------------------------------------------------------*/ class CMD_STORE : public CMD { public: void do_it(CS& cmd, CARD_LIST*) { do_probe(cmd,PROBE_LISTS::store); } } p0; DISPATCHER::INSTALL d0(&command_dispatcher, "store", &p0); /*--------------------------------------------------------------------------*/ class CMD_ALARM : public CMD { public: void do_it(CS& cmd, CARD_LIST*) { do_probe(cmd,PROBE_LISTS::alarm); } } p1; DISPATCHER::INSTALL d1(&command_dispatcher, "alarm", &p1); /*--------------------------------------------------------------------------*/ class CMD_PLOT : public CMD { public: void do_it(CS& cmd, CARD_LIST*) { IO::plotset = true; do_probe(cmd,PROBE_LISTS::plot); } } p2; DISPATCHER::INSTALL d2(&command_dispatcher, "iplot|plot", &p2); /*--------------------------------------------------------------------------*/ class CMD_PRINT : public CMD { public: void do_it(CS& cmd, CARD_LIST*) { IO::plotset = false; do_probe(cmd,PROBE_LISTS::print); } } p3; DISPATCHER::INSTALL d3(&command_dispatcher, "iprint|print|probe", &p3); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_sim.cc000066400000000000000000000037511145401216200132500ustar00rootroot00000000000000/*$Id: c_sim.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * command interface functions associated with the SIM base class */ //testing=script 2006.07.17 #include "u_sim_data.h" #include "c_comand.h" #include "globals.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class CMD_MARK : public CMD { public: void do_it(CS&, CARD_LIST*) {itested(); _sim->_freezetime = true; } } p6; DISPATCHER::INSTALL d6(&command_dispatcher, "mark|freeze", &p6); /*--------------------------------------------------------------------------*/ class CMD_UNMARK : public CMD { public: void do_it(CS&, CARD_LIST*) { _sim->_freezetime = false; } } p7; DISPATCHER::INSTALL d7(&command_dispatcher, "unmark|unfreeze", &p7); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_status.cc000066400000000000000000000066441145401216200140070ustar00rootroot00000000000000/*$Id: c_status.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Displays the status of the system. Makes all the calculations associated * with allocating memory but does not actually allocate it, unless necessary * to make the rest of the calculations. * * If "allocate" is changed, this must also be changed. */ //testing=script 2006.07.17 #include "u_sim_data.h" #include "u_status.h" #include "c_comand.h" #include "globals.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class CMD_STATUS : public CMD { public: void do_it(CS& cmd, CARD_LIST*) { IO::mstdout << "Gnucap System status\n"; if (!cmd.umatch("n{otime} ")) { ::status.compute_overhead(); IO::mstdout << "command ------ last -- total\n" << ::status.get << ::status.op << ::status.dc << ::status.tran << ::status.four << ::status.ac << "function ----- last -- total\n" << ::status.set_up << ::status.order << "function ----- last -- total\n" << ::status.advance << ::status.queue << ::status.evaluate << ::status.load << ::status.lud << ::status.back << ::status.review << ::status.accept << ::status.output << ::status.overhead; if (OPT::showall) {itested(); IO::mstdout << ::status.aux1 << ::status.aux2 << ::status.aux3; } IO::mstdout << ::status.total; } IO::mstdout << "iterations: op=" << _sim->_iter[s_OP] << ", dc=" << _sim->_iter[s_DC] << ", tran=" << _sim->_iter[s_TRAN] << ", fourier=" << _sim->_iter[s_FOURIER] << ", total=" << _sim->_iter[iTOTAL] << "\n"; for(DISPATCHER::const_iterator i = status_dispatcher.begin(); i != status_dispatcher.end(); ++i) { CKT_BASE* c = i->second; if (c) { IO::mstdout << c->status(); }else{ } } IO::mstdout << "nodes: user=" << _sim->_user_nodes << ", subckt=" << _sim->_subckt_nodes << ", model=" << _sim->_model_nodes << ", total=" << _sim->_total_nodes << "\n"; IO::mstdout.form("dctran density=%.1f%%, ac density=%.1f%%\n", _sim->_aa.density()*100., _sim->_acx.density()*100.); } } p; DISPATCHER::INSTALL d(&command_dispatcher, "status", &p); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_sweep.cc000066400000000000000000000104771145401216200136060ustar00rootroot00000000000000/*$Id: c_sweep.cc,v 26.83 2008/06/05 04:46:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Step a parameter and repeat a group of commands */ //testing=none 2006.07.17 #include "c_comand.h" #include "globals.h" extern int swp_count[], swp_steps[]; extern int swp_type[]; extern int swp_nest; /*--------------------------------------------------------------------------*/ namespace { static std::string tempfile = STEPFILE; /*--------------------------------------------------------------------------*/ static void setup(CS& cmd) { for (;;) { if (cmd.is_digit()) { swp_steps[swp_nest] = cmd.ctoi() ; swp_steps[swp_nest] = (swp_steps[swp_nest]) ? swp_steps[swp_nest]-1 : 0; }else if (cmd.umatch("li{near} ")) { swp_type[swp_nest] = 0; }else if (cmd.umatch("lo{g} ")) { swp_type[swp_nest] = 'L'; }else{ break; } } } /*--------------------------------------------------------------------------*/ static void buildfile(CS& cmd) { static FILE *fptr; setup(cmd); if (fptr) { fclose(fptr); }else{ } fptr = fopen(tempfile.c_str(), "w"); if (!fptr) { throw Exception_File_Open("can't open temporary file:" + tempfile); }else{ } fprintf(fptr, "%s\n", cmd.fullstring().c_str()); for (;;) { char buffer[BUFLEN]; getcmd(">>>", buffer, BUFLEN); if (Umatch(buffer,"go ")) { break; }else{ } fprintf(fptr, "%s\n", buffer); } fclose(fptr); fptr = NULL; } /*--------------------------------------------------------------------------*/ static void doit(CARD_LIST* scope) { static FILE *fptr; for (swp_count[swp_nest]=0; swp_count[swp_nest]<=swp_steps[swp_nest]; ++swp_count[swp_nest]) { if (fptr) { fclose(fptr); }else{ } fptr = fopen(tempfile.c_str(), "r"); if (!fptr) { throw Exception_File_Open("can't open " + tempfile); }else{ } char buffer[BUFLEN]; fgets(buffer,BUFLEN,fptr); { CS cmd(CS::_STRING, buffer); //fgets from local file, obsolete if (cmd.umatch("sw{eep} ")) { setup(cmd); }else{ throw Exception("bad file format: " + tempfile); } unsigned ind = cmd.cursor(); strncpy(buffer, "fault ", ind); buffer[ind-1] = ' '; /* make sure there is a delimiter */ } /* in case the words run together */ for (;;) { /* may wipe out one letter of fault */ { CS cmd(CS::_STRING, buffer); //fgets from local file, obsolete CMD::cmdproc(cmd, scope); } if (!fgets(buffer,BUFLEN,fptr)) { break; }else{ } { CS cmd(CS::_STRING, buffer); //fgets from local file, obsolete if (cmd.umatch("sw{eep} ")) { cmd.warn(bDANGER, "command not allowed in sweep"); buffer[0] = '\''; }else{ } } IO::mstdout << swp_count[swp_nest]+1 << "> " << buffer; } } fclose(fptr); fptr = NULL; swp_count[swp_nest] = 0; } /*--------------------------------------------------------------------------*/ class CMD_SWEEP : public CMD { public: void do_it(CS& cmd, CARD_LIST* Scope) { if (cmd.more()) { buildfile(cmd); }else{ } doit(Scope); command("unfault", Scope); } } p; DISPATCHER::INSTALL d(&command_dispatcher, "sweep", &p); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/c_system.cc000066400000000000000000000060651145401216200140050ustar00rootroot00000000000000/*$Id: c_system.cc,v 26.83 2008/06/05 04:46:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * system calls: change directory, invoke another program, invoke editor, etc. */ //testing=none 2006.07.17 #include "c_comand.h" #include "globals.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ /* cmd_edit: (command) invoke user defined editor on the netlist * if command has an argument, it edits that file instead * else actually edits a temporary file, and reads it back. */ class CMD_EDIT : public CMD { public: void do_it(CS& cmd, CARD_LIST* Scope) {itested(); std::string editor(OS::getenv("EDITOR")); if (editor == "") { throw Exception("no editor defined\n" "You need to set the EDITOR environment variable."); }else{ if (cmd.more()) {itested(); OS::system(editor + ' ' + cmd.tail()); }else{ std::string temp_file("/tmp/gnucap" + to_string(unsigned(time(NULL)))); command("save " + temp_file + " quiet", Scope); OS::system(editor + ' ' + temp_file); command("get " + temp_file + " quiet", Scope); OS::remove(temp_file); } } } } p1; DISPATCHER::INSTALL d1(&command_dispatcher, "edit", &p1); /*--------------------------------------------------------------------------*/ class CMD_SYSTEM : public CMD { public: void do_it(CS& cmd, CARD_LIST*) {itested(); if (cmd.more()) {itested(); OS::system(cmd.tail()); }else{ OS::system(SHELL); } } } p2; DISPATCHER::INSTALL d2(&command_dispatcher, "system|!", &p2); /*--------------------------------------------------------------------------*/ class CMD_CHDIR : public CMD { public: void do_it(CS& cmd, CARD_LIST*) {itested(); if (cmd.more()) { OS::chdir(cmd.ctos("")); }else{ } IO::mstdout << OS::getcwd() << '\n'; } } p3; DISPATCHER::INSTALL d3(&command_dispatcher, "chdir|cd", &p3); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ src/configure.old000077500000000000000000000035261145401216200143330ustar00rootroot00000000000000#!/bin/sh rm -f gnucap-modelgen ln -s ../modelgen/O/gnucap-modelgen . mkdir O echo "CCFLAGS = \\" >Make.ccflags echo "LIBS = -ldl \\" >Make.libs (cd O; rm -f gnucap-modelgen; ln -s ../../modelgen/O/gnucap-modelgen gnucap-modelgen) rm -f a.out g++ -lreadline -ltermcap test_readline.cc if [ -f a.out ] ; then echo "using readline" echo "-DHAVE_LIBREADLINE \\" >>Make.ccflags echo "-lreadline -ltermcap \\" >>Make.libs else echo "either libtermcap or libreadline is missing - not using readline" fi rm -f a.out echo "-DUNIX -O2 -DNDEBUG -I.. -I. -W" >>Make.ccflags echo "" >>Make.libs echo "" >>Make.libs cat <Make.sys #------------------------------------------------------------------------ VPATH = .:.. CCC = g++ LDFLAGS = -rdynamic .SUFFIXES: .SUFFIXES: .o .cc .cc.o:; \$(CCC) \$(CCFLAGS) -c \$< #------------------------------------------------------------------------ \$(TARGET): \$(OBJS) rm -f \$@ \$(CCC) \$(CCFLAGS) \$(OBJS) \$(LIBS) \$(LDFLAGS) -o \$@ #------------------------------------------------------------------------ CAT_EOF cat Make.ccflags Make.libs Make.sys >Make2 rm Make.ccflags Make.libs Make.sys #------------- Stuff added to enable --prefix -------------- if test "x$1" != "x"; then # echo Found input parameter -- $1 # Now see if the parameter is --prefix= if test "x${1#--prefix=}" != "x$1"; then # echo "Found --prefix in input args. Setting prefix directory." prefix=${1#--prefix=} else # echo "Found unrecognized parameter in input args." # Just use the default prefix dir. prefix=/usr/local fi else # echo "No input parameter found." # Just use the default prefix dir prefix=/usr/local fi sed -e "s#/usr/local#$prefix#" Makefile.template > Makefile #---------------------------------------------------------------- exit 0 src/constant.h000066400000000000000000000112721145401216200136460ustar00rootroot00000000000000/*$Id: constant.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * defined constants for just about everything */ //testing=trivial 2006.07.17 #ifndef CONSTANT_H #define CONSTANT_H #include "md.h" /*--------------------------------------------------------------------------*/ /* The names are chosen according to Verilog-A spec. */ /* Commented out means they are defined in a standard header, usually */ /* or there is some discrepancy of the correct value */ /* standard mathematical constants */ //double const M_PI = 3.1415926535897932384626433832795028841972; double const M_TWO_PI = M_PI * 2; //double const M_PI_2 = M_PI / 2; //double const M_PI_4 = M_PI / 4; //double const M_1_PI = 1 / M_PI; //double const M_2_PI = 2 / M_PI; //double const M_2_SQRTPI = 2 / sqrt(M_PI); //double const M_E = 2.7182818284590452354; //double const M_LOG2E = 1.4426950408889634074; // log2(M_E) //double const M_LOG10E = 0.43429448190325182765; // log10(M_E) //double const M_LN2 = 0.69314718055994530942; // log(2) //double const M_LN10 = 2.3025809299404568402; // log(10) //double const M_SQRT2 = 1.4142135623730904880; // sqrt(2) //double const M_SQRT1_2 = 1 / M_SQRT_2; /* extra mathematical constants */ //double const DTOR = 0.0174532925199432957692369076848861271344; //double const RTOD = 57.2957795130823208768; double const DTOR = M_PI / 180; double const RTOD = 180 / M_PI; /* standard physical constants ref: http://physics.nist.gov */ double const P_Q = 1.6021918e-19; // charge of an electron, (spice) //double const P_Q = 1.60217653e-19; // charge of an electron, (nist) double const P_C = 2.99792458e8; // speed of light m/s double const P_K = 1.3806226e-23; // Boltzmann's constant J/K (spice) //double const P_K = 1.3806505e-23; // Boltzmann's constant J/K (nist) double const P_H = 6.6260693e-34; // Planck's constant J-s double const P_U0 = M_PI * 4.0e-7; // permeability of vaccuum H/m double const P_EPS0 = 8.854214871e-12; // permittivity of air F/m(spice) //double const P_EPS0 = 8.854187817e-12; // permittivity of vaccuum F/m(nist) //double const P_EPS0 = 1/(P_U0*P_C*P_C);// permittivity of vaccuum F/m(nist) double const P_CELSIUS0 = 273.15; // 0 Celsius /* extra physical constants */ double const P_EPS_SI = 11.7*P_EPS0; // permittivity of silicon (1.0359e-10) double const P_EPS_OX = 3.9*P_EPS0; // permittivity of oxide (3.45e-11) double const P_K_Q = P_K/P_Q; /* dimension conversions. * Hopefully, all internal distances are in meters. * (except for some Berkeley models) * In some cases the user data is in other units */ double const CM2M = 1e-2; /* centimeters to meters */ double const CM2M2 = 1e-4; /* ........... squared */ double const ICM2M = 1e2; /* inverse ........... */ double const ICM2M2 = 1e4; /* inverse ........... squared */ double const ICM2M3 = 1e6; /* inverse ........... cubed */ double const MICRON2METER = 1e-6; /* microns to meters */ #ifdef HAS_NUMERIC_LIMITS double const MAXDBL = std::numeric_limits::max(); #else double const MAXDBL = DBL_MAX; #endif double const BIGBIG = (MAXDBL)*(.9247958); /* unlikely number */ //double const OVERDUE = -(MAXDBL)*(.9347958);/* unlikely number */ double const NEVER = (MAXDBL)*(.9447958); /* unlikely number */ double const NOT_INPUT = -(MAXDBL)*(.9547658); /* unlikely number */ double const NOT_VALID = -(MAXDBL)*(.9647958); /* unlikely number */ double const LINEAR = -(MAXDBL)*(.9747958); /* unlikely number */ double const LOGBIGBIG = log(BIGBIG); double const VOLTMIN = 1.0e-50; double const PWRMIN = 1.0e-100; const char TOKENTERM[] = ",=()[]"; enum {FILE_OK=0, FILE_BAD=-1}; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_admit.cc��������������������������������������������������������������������������������������0000664�0000000�0000000�00000014023�11454012162�0013551�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_admit.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * admittance devices: * self-admittance (old Y device) * y.x = volts, y.f0 = amps, ev = y.f1 = mhos. * m.x = volts, m.c0 = amps, acg = m.c1 = mhos. * trans-admittance (VCCS, G device) * voltage controlled admittance * y.x = volts(control), y.f0 = mhos, ev = y.f1 = mhos/volt * m.x = volts(control), m.c0 = 0, acg = m.c1 = mhos * _loss0 == 1/R. (mhos) */ //testing=script 2006.07.17 #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class DEV_ADMITTANCE : public ELEMENT { protected: explicit DEV_ADMITTANCE(const DEV_ADMITTANCE& p) :ELEMENT(p) {} public: explicit DEV_ADMITTANCE() :ELEMENT() {} protected: // override virtual char id_letter()const {return 'Y';} std::string value_name()const {return "g";} std::string dev_type()const {return "admittance";} int max_nodes()const {return 2;} int min_nodes()const {return 2;} int matrix_nodes()const {return 2;} int net_nodes()const {return 2;} bool has_iv_probe()const {return true;} bool use_obsolete_callback_parse()const {return true;} CARD* clone()const {return new DEV_ADMITTANCE(*this);} void precalc_last(); void tr_iwant_matrix() {tr_iwant_matrix_passive();} void tr_begin(); bool do_tr(); void tr_load() {tr_load_passive();} void tr_unload() {tr_unload_passive();} double tr_involts()const {return tr_outvolts();} double tr_involts_limited()const {return tr_outvolts_limited();} void ac_iwant_matrix() {ac_iwant_matrix_passive();} void ac_begin() {_acg = _ev = _y[0].f1;} void do_ac(); void ac_load() {ac_load_passive();} COMPLEX ac_involts()const {untested();return ac_outvolts();} std::string port_name(int i)const { assert(i >= 0); assert(i < 2); static std::string names[] = {"p", "n"}; return names[i]; } }; /*--------------------------------------------------------------------------*/ class DEV_VCCS : public DEV_ADMITTANCE { protected: explicit DEV_VCCS(const DEV_VCCS& p) :DEV_ADMITTANCE(p) {} public: explicit DEV_VCCS() :DEV_ADMITTANCE() {} protected: // override virtual char id_letter()const {return 'G';} std::string value_name()const {return "gm";} std::string dev_type()const {return "vccs";} int max_nodes()const {return 4;} int min_nodes()const {return 4;} int matrix_nodes()const {return 4;} int net_nodes()const {return 4;} bool has_iv_probe()const {return false;} CARD* clone()const {return new DEV_VCCS(*this);} void tr_iwant_matrix() {tr_iwant_matrix_active();} void tr_load() {tr_load_active();} void tr_unload() {untested();tr_unload_active();} double tr_involts()const {return dn_diff(_n[IN1].v0(), _n[IN2].v0());} double tr_involts_limited()const {return volts_limited(_n[IN1],_n[IN2]);} void ac_iwant_matrix() {ac_iwant_matrix_active();} void ac_load() {ac_load_active();} COMPLEX ac_involts()const {untested();return _n[IN1]->vac() - _n[IN2]->vac();} std::string port_name(int i)const { assert(i >= 0); assert(i < 4); static std::string names[] = {"sink", "src", "ps", "ns"}; return names[i]; } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void DEV_ADMITTANCE::precalc_last() { ELEMENT::precalc_last(); set_constant(!has_tr_eval()); set_converged(!has_tr_eval()); } /*--------------------------------------------------------------------------*/ void DEV_ADMITTANCE::tr_begin() { ELEMENT::tr_begin(); _m0.x = _y[0].x; _m0.c1 = _y[0].f1; _m0.c0 = 0.; _m1 = _m0; assert(_loss0 == 0.); assert(_loss1 == 0.); } /*--------------------------------------------------------------------------*/ bool DEV_ADMITTANCE::do_tr() { if (using_tr_eval()) { _y[0].x = _m0.x = tr_involts_limited(); _y[0].f0 = _m0.c1 * _m0.x + _m0.c0; //BUG// patch for diode tr_eval(); assert(_y[0].f0 != LINEAR); store_values(); q_load(); _m0 = CPOLY1(_y[0]); }else{ assert(_y[0].f0 == LINEAR); assert(_y[0].f1 == value()); assert(_m0.c1 == _y[0].f1); assert(_m0.c0 == 0.); assert(_y1 == _y[0]); assert(converged()); } return converged(); } /*--------------------------------------------------------------------------*/ void DEV_ADMITTANCE::do_ac() { if (using_ac_eval()) {untested(); ac_eval(); _acg = _ev; }else{ assert(_ev == _y[0].f1); assert(has_tr_eval() || _ev == double(value())); } assert(_acg == _ev); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_ADMITTANCE p1; DEV_VCCS p2; DISPATCHER::INSTALL d1(&device_dispatcher, "Y|admittance", &p1), d2(&device_dispatcher, "G|vccs", &p2); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_bjt.model�������������������������������������������������������������������������������������0000664�0000000�0000000�00000063072�11454012162�0013755�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: d_bjt.model,v 26.136 2009/12/08 02:03:49 al Exp $ -*- C++ -*- * Copyright (C) 2002 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Berkeley BJT model * Derived from Spice code, both from 2g6 and 3f4 * Recoded for Gnucap model compiler, Al Davis, 2002 *------------------------------------------------------------------ * data structures and defaults for bjt model. * * netlist syntax: * device: qxxxx c b e s mname * model: .model mname NPN * or .model mname PNP * * known BUGs * 1. excess phase partially implemented, disabled, as if PTF == 0. */ /*--------------------------------------------------------------------------*/ h_headers { #include "d_diode.h" } cc_headers { #include "u_limit.h" } /*--------------------------------------------------------------------------*/ device BUILT_IN_BJT { parse_name bjt; model_type BUILT_IN_BJT; id_letter Q; circuit { sync; ports {c b e} {s}; local_nodes { ic short_to=c short_if="!OPT::rstray || m->rc == 0."; ib short_to=b short_if="!OPT::rstray || (m->rb == 0. && m->rbm == 0.)"; ie short_to=e short_if="!OPT::rstray || m->re == 0."; } // basics cpoly_g Ice {ic,ie ib,ie} state=ccexxx; // cce, go, gm cpoly_g Ipi {ib ie} state=cpixxx; // cpi, gpi cpoly_g Imu {ib ic} state=cmuxxx; // cmu, gmu // junction charge effects fpoly_cap Cbx {b ic} state=qbx; // qbx, cqbx fpoly_cap Cbc {ib ic} state=qbc; // qbc, cqbc fpoly_cap Ccs {s ic} state=qcs // qcs, cqcs omit="!(_n[n_s].n_())"; fpoly_cap Cbe {ib ie ib ic} state=qbe; // qbe, cqbe, geqbc // parasitics resistor Rc {c ic} value="m->rc / c->area" omit="!OPT::rstray || m->rc == 0."; // gcpr resistor Re {e ie} value="m->re / c->area" omit="!OPT::rstray || m->re == 0."; // gepr cpoly_g Yb {b ib} state=ixxxx // gx. should be "eval" omit="!OPT::rstray || (m->rb == 0. && m->rbm == 0.)"; capacitor Cbcp {b c} value="m->cbcp * c->area" omit="!OPT::cstray || m->cbcp == 0."; capacitor Cbep {b e} value="m->cbep * c->area" omit="!OPT::cstray || m->cbep == 0."; capacitor Cbs {b s} value="(m->cbsp + m->ccsp) * c->area" omit="!OPT::cstray || ((m->cbsp + m->ccsp) == 0.)"; } tr_probe { v = "@n_c[V] - @n_e[V]"; "vbei{nt}" = "vbe"; "vbci{nt}" = "vbc"; "vbxi{nt}" = "vbx"; "vcsi{nt}" = "vcs"; vbs = "@n_b[V] - @n_s[V]"; vbe = "@n_b[V] - @n_e[V]"; vbc = "@n_b[V] - @n_c[V]"; vbx = "@n_b[V] - @n_ib[V]"; vcs = "@n_c[V] - @n_s[V]"; vcb = "@n_c[V] - @n_b[V]"; vce = "@n_c[V] - @n_e[V]"; ves = "@n_e[V] - @n_s[V]"; veb = "@n_e[V] - @n_b[V]"; vec = "@n_e[V] - @n_c[V]"; vb = "@n_b[V]"; vc = "@n_c[V]"; ve = "@n_e[V]"; vs = "@n_s[V]"; vbi = "@n_ib[V]"; vci = "@n_ic[V]"; vei = "@n_ie[V]"; "i" = "cce"; "ice" = "cce"; "iceo{ffset}" = "ccexxx"; hoe = "go"; "ro{e}" = "(go != 0.) ? 1/go : BIGBIG"; ipi = "cpi"; "ipio{ffset}" = "cpixxx"; rpi = "(gpi != 0.) ? 1/gpi : BIGBIG"; hie = "(gpi != 0.) ? 1/gpi : BIGBIG"; imu = "cmu"; "imuo{ffset}" = "cmuxxx"; rmu = "(gmu != 0.) ? 1/gmu : BIGBIG"; ib = "cpi + cmu"; rx = "(gx != NA) ? 1/gx : 0."; ic = "cce - cmu"; ie = "-cce -cpi"; cbx = "cqbx"; cbc = "cqbc"; cmu = "cqbc"; ccs = "cqcs"; cbe = "cqbe"; cpi = "cqbe"; p = "@Ice[P] + @Ipi[P] + @Imu[P] + @Rc[P] + @Re[P] + @Yb[P] + @Cbx[P] + @Cbc[P] + @Ccs[P] + @Cbe[P]"; pd = "@Ice[PD] + @Ipi[PD] + @Imu[PD] + @Rc[PD] + @Re[PD] + @Yb[PD] + @Cbx[PD] + @Cbc[PD] + @Ccs[PD] + @Cbe[PD]"; ps = "@Ice[PS] + @Ipi[PS] + @Imu[PS] + @Rc[PS] + @Re[PS] + @Yb[PS] + @Cbx[PS] + @Cbc[PS] + @Ccs[PS] + @Cbe[PS]"; status = "static_cast(converged() * 2)"; } device { calculated_parameters { double vbe "B-E voltage"; // gather double vbc "B-C voltage"; double vbx "B-C voltage (ext base)"; double vcs "C-S voltage"; double cce "collector-emitter current"; double ccexxx; double go "Small signal output conductance"; double gm "Small signal transconductance"; double cpi "emitter-base current"; double cpixxx; double gpi "Small signal input conductance - pi"; double cmu "collector-base current"; double cmuxxx; double gmu "Small signal conductance - mu"; double ixxxx "Current offset at base node, constant" default=0.; double gx "dix/dvbb Conductance from base to internal base"; double qbx "Charge storage B-X junction"; double cqbx "Cap. due to charge storage in B-X jct."; // cbx, capbx double qbc "Charge storage B-C junction"; double cqbc "Cap. due to charge storage in B-C jct."; // cmu, capbc double qcs "Charge storage C-S junction"; double cqcs "Cap. due to charge storage in C-S jct."; // ccs, capcs double qbe "Charge storage B-E junction"; double cqbe "Cap. due to charge storage in B-E jct."; // cpi, capbe double geqcb "d(Ieb)/d(Vcb)"; double cexbc_0 "Total Capacitance in B-X junction"; // ?? double cexbc_1 ""; double cexbc_2 ""; double _dt_0 "time step"; double _dt_1 ""; } } common { unnamed area; raw_parameters { double area "area factor" name=Area positive default=1.; bool off "device initially off" name=OFF default=false print_test=off; double icvbe "Initial B-E voltage" name="ICVBE" default=NA; double icvce "Initial C-E voltage" name="ICVCE" default=NA; double temp_c "instance temperature" name="TEMP" default=NA; } calculated_parameters { double oik "" calculate="m->invrollofff / c->area"; double oikr "" calculate="m->invrolloffr / c->area"; } } tr_eval { int foo=3; } } /*--------------------------------------------------------------------------*/ model BUILT_IN_BJT { level 1; dev_type BUILT_IN_BJT; hide_base; inherit BUILT_IN_DIODE; public_keys { npn polarity=pN; pnp polarity=pP; npn1 polarity=pN; pnp1 polarity=pP; } independent { override { double kf "Flicker Noise Coefficient" name=KF default=0.; double af "Flicker Noise Exponent" name=AF default=1.; } raw_parameters { int level "dummy" name=LEVEL default=1 print_test=false; // basic double bf "Ideal forward beta" name=BF alt_name=BFM default=100.; double br "Ideal reverse beta" name=BR alt_name=BRM default=1.; double ibc "bc Saturation Current" name=IBC default=NA print_test="ibe != ibc" final_default="((has_hard_value(i_s)) ? i_s : 1e-16)"; double ibe "be Saturation Current" name=IBE default=NA print_test="ibe != ibc" final_default="((has_hard_value(i_s)) ? i_s : 1e-16)"; double i_s "Saturation Current" name=IS default=NA print_test="ibe == ibc" final_default="((ibe == ibc) ? ibe : NA)"; //double iss "bulk to collector or base sat current (ignored)" //name=ISS default=0; //double expli "current explosion factor (ignored)" //name=EXPLI default=1e15; double nf "Forward emission coefficient" name=NF default=1.; double nr "Reverse emission coefficient" name=NR default=1.; //double ns "substrate leakage emission coefficient (ignored)" //name=NS default=1; //int subs "geometry, +1=vertical, -1=lateral (ignored)", name=SUBS //default="(polarity==pP) ? -1 : 1"; // base width modulation double vaf "Forward Early voltage" name=VAf alt_name=VA\0VBF default=NA; double var "Reverse Early voltage" name=VAR alt_name=VB default=NA; // low current beta degeneration double isc "B-C leakage saturation current" name=ISC default=NA final_default="(c4*ibc)"; double c4 "obsolete, don't use" name=C4 alt_name=JLC default=0.; double nc "B-C leakage emission coefficient" name=NC default=2.; double ise "B-E leakage saturation current" name=ISE default=NA final_default="(c2*ibe)"; double c2 "obsolete, don't use" name=C2 alt_name=JLE default=0.; double ne "B-E leakage emission coefficient" name=NE default=1.5; // high current beta degeneration double ikf "Forward beta roll-off corner current" name=IKf alt_name=IK\0JBF default=NA; double ikr "reverse beta roll-off corner current" name=IKR alt_name=JBR default=NA; // parasitic resistance double irb "Current for base resistance=(rb+rbm)/2" name=IRB alt_name=JRB\0IOB default=NA; double rb "Zero bias base resistance" name=RB default=0.; double rbm "Minimum base resistance" name=RBM default=NA final_default=rb; double re "Emitter resistance" name=RE default=0.; double rc "Collector resistance" name=RC default=0.; // parasitic capacitance double cbcp "external BC capacitance" name=CBCP print_test="cbcp!=0." default=0.; double cbep "external BE capacitance" name=CBEP print_test="cbep!=0." default=0.; double cbsp "external BS capacitance (lateral)" name=CBSP print_test="cbsp!=0." default=0.; double ccsp "external BS capacitance (vertical)" name=CCSP print_test="ccsp!=0." default=0.; // junction capacitance double cjc "Zero bias B-C depletion capacitance" name=CJC default=0.; double cje "Zero bias B-E depletion capacitance" name=CJE default=0.; double cjs "Zero bias C-S capacitance" name=CJS alt_name=CCS\0CSUB default=0.; double fc "Forward bias junction fit parameter" name=FC default=NA final_default=.5 quiet_max=.9999; double mjc "B-C junction grading coefficient" name=MJC alt_name=MC\0MJ default=.33; double mje "B-E junction grading coefficient" name=MJE alt_name=ME default=.33; double mjs "Substrate junction grading coefficient" name=MJS alt_name=MSub\0MS\0ESUB default=0.; // alt name ESUB?? double vjc "B-C built in potential" name=VJC alt_name=PC default=.75; double vje "B-E built in potential" name=VJE alt_name=PE default=.75; double vjs "Substrate junction built in potential" name=VJS alt_name=PSub\0PS default=.75; double xcjc "Fraction of B-C cap to internal base" name=XCJC alt_name=CDIS default=1.; // transit time double itf "High current dependence of TF" name=ITF alt_name=JTF default=0.; double ptf "Excess phase" name=PTf default=0.; double tf "Ideal forward transit time" name=TF default=0.; double tr "Ideal reverse transit time" name=TR default=0.; double vtf "Voltage giving VBC dependence of TF" name=VTF default=NA; double xtf "Coefficient for bias dependence of TF" name=XTF default=0.; // temperature effects double xtb "Forward and reverse beta temp. exp." name=XTB alt_name=TB default=0.; // alt name TCB double xti "Temp. exponent for IS" name=XTI default=3.; double eg "Energy gap for IS temp. dependency" name=EG default=1.11; } calculated_parameters { double tnom_k "nominal temperature, kelvin" calculate="_tnom_c + P_CELSIUS0"; polarity_t polarity "" default=pN; double invearlyvoltf "Inverse early voltage:forward" name=INVEARLYVOLTF calculate="(has_nz_value(vaf)) ? 1./vaf : 0."; double invearlyvoltr "Inverse early voltage:reverse" name=INVEARLYVOLTR calculate="(has_nz_value(var)) ? 1./var : 0."; double invrollofff "Inverse roll off - forward" name=INVROLLOFFF calculate="(has_nz_value(ikf)) ? 1./ikf : 0."; double invrolloffr "Inverse roll off - reverse" name=INVROLLOFFR calculate="(has_nz_value(ikr)) ? 1./ikr : 0."; double transtimevbcfact "Transit time VBC factor" name=TRANSTIMEVBCFACT calculate="(has_nz_value(vtf)) ? 1./(vtf*1.44) : 0."; double excessphasefactor "Excess phase fact." name=EXCESSPHASEFACTOR calculate="(ptf * DTOR) * tf"; double xfc "" calculate="log(1 - fc)"; double f2 "" calculate="exp((1 + mje) * xfc)"; double f3 "" calculate="1 - fc * (1 + mje)"; double f6 "" calculate="exp((1 + mjc) * xfc)"; double f7 "" calculate="1 - fc * (1 + mjc)"; } } temperature_dependent { calculated_parameters { double vt ""; //double is "BJTtSatCur" calculate = "m->is * factor"; double ibc "BJTtSatCur" calculate = "m->ibc * factor"; double ibe "BJTtSatCur" calculate = "m->ibe * factor"; double BetaF "BJTtBetaF" calculate = "m->bf * bfactor"; double BetaR "BJTtBetaR" calculate = "m->br * bfactor"; double BEleakCur "BJTtBEleakCur" calculate = "m->ise * exp(factlog/m->ne) / bfactor"; double BCleakCur "BJTtBCleakCur" calculate = "m->isc * exp(factlog/m->nc) / bfactor"; double BEpot "BJTtBEpot"; double BEcap "BJTtBEcap"; double DepCap ""; double f1 ""; double BCpot "BJTtBCpot"; double BCcap "BJTtBCcap"; double f4 ""; double f5 ""; double Vcrit "" calculate="vt * log(vt / (M_SQRT2 * m->ibe))"; } code_pre { const double reftemp = 300.15; double temp_k = ((has_hard_value(c->temp_c)) ? c->temp_c : d->_sim->_temp_c) + P_CELSIUS0; double fact1 = m->tnom_k / reftemp; double fact2 = temp_k / reftemp; double tempratio = temp_k / m->tnom_k; // fact2/fact1 double kt = temp_k * P_K; vt = temp_k * P_K_Q; double egap = 1.16 - (7.02e-4*temp_k*temp_k) / (temp_k+1108.); // egfet // double arg = (m->eg*tempratio - egap) / (2*kt); double arg = -egap/(2 * kt) + 1.1150877 / (P_K * (reftemp+reftemp)); double pbfact = -2 * vt * (1.5 * log(fact2) + P_Q * arg); double ratlog = log(tempratio); double ratio1 = tempratio - 1; double factlog = ratio1 * m->eg / vt + m->xti * ratlog; double factor = exp(factlog); double bfactor = exp(ratlog * m->xtb); } code_post { { double pbo = (m->vje - pbfact) / fact1; BEpot = fact2 * pbo + pbfact; double gmaold = (m->vje - pbo) / pbo; double gmanew = (BEpot - pbo) / pbo; BEcap = (m->cje / (1 + m->mje * (4e-4*(m->tnom_k-reftemp)-gmaold))) * (1 + m->mje * (4e-4*(temp_k-reftemp)-gmanew)); DepCap = m->fc * BEpot; f1 = BEpot * (1 - exp((1 - m->mje) * m->xfc)) / (1 - m->mje); } { double pbo = (m->vjc - pbfact) / fact1; BCpot = fact2 * pbo + pbfact; double gmaold = (m->vjc - pbo) / pbo; double gmanew = (BCpot - pbo) / pbo; BCcap = (m->cjc / (1 + m->mjc * (4e-4*(m->tnom_k-reftemp)-gmaold))) * (1 + m->mjc * (4e-4*(temp_k-reftemp)-gmanew)); f4 = m->fc * BCpot; f5 = BCpot * (1 - exp((1 - m->mjc) * m->xfc)) / (1 - m->mjc); } } } tr_eval { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - trace0("--------------------------"); trace1(d->long_label().c_str(), d->evaliter()); trace4("", d->vbe, d->vbc, d->vbx, d->vcs); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double cbe, gbe; { // d->cpi, d->gpi, d->cpixxx // uses: d->vbe double cben, gben; double vtn = t->vt * m->nf; double csat = t->ibe * c->area; double C2 = t->BEleakCur * c->area; if (d->vbe > -5 * vtn) { double evbe = exp(d->vbe / vtn); cbe = csat * (evbe-1) + OPT::gmin * d->vbe; gbe = csat * evbe/vtn + OPT::gmin; if (C2 == 0.) { cben = 0.; gben = 0.; }else{ double vte = m->ne * t->vt; double evben = exp(d->vbe / vte); cben = C2 * (evben-1); gben = C2 * evben/vte; } trace4("vbe on", cbe, gbe, cben, gben); }else{ gbe = -csat/d->vbe + OPT::gmin; cbe = gbe * d->vbe; gben = -C2 / d->vbe; cben = gben * d->vbe; trace4("vbe off", cbe, gbe, cben, gben); } d->cpi = cbe / t->BetaF + cben; d->gpi = gbe / t->BetaF + gben; d->cpixxx = d->cpi - d->vbe * d->gpi; trace3("", t->BetaF, d->cpi, d->gpi); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double cbc, gbc, cbcn; { // d->cmu, d->gmu, d->cmuxxx // uses: d->vbc double gbcn; double vtn = t->vt * m->nr; double csat = t->ibc * c->area; double C4 = t->BCleakCur * c->area; if (d->vbc > -5 * vtn) { double evbc = exp(d->vbc / vtn); cbc = csat * (evbc-1) + OPT::gmin * d->vbc; gbc = csat * evbc/vtn + OPT::gmin; if (C4 == 0.) { cbcn = 0.; gbcn = 0.; }else{ double vtc = m->nc * t->vt; double evbcn = exp(d->vbc / vtc); cbcn = C4 * (evbcn-1); gbcn = C4 * evbcn/vtc; } trace4("vbc on", cbc, gbc, cbcn, gbcn); }else{ gbc = -csat/d->vbc + OPT::gmin; cbc = gbc * d->vbc; gbcn = -C4 / d->vbc; cbcn = gbcn * d->vbc; trace4("vbc off", cbc, gbc, cbcn, gbcn); } d->cmu = cbc / t->BetaR + cbcn; d->gmu = gbc / t->BetaR + gbcn; d->cmuxxx = d->cmu - d->vbc * d->gmu; trace3("", t->BetaR, d->cmu, d->gmu); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // determine base charge terms double qb, dqbdve, dqbdvc; { double q1 = 1 / (1 - m->invearlyvoltf*d->vbc - m->invearlyvoltr*d->vbe); if(c->oik == 0. && c->oikr == 0.) { qb = q1; dqbdve = q1 * qb * m->invearlyvoltr; dqbdvc = q1 * qb * m->invearlyvoltf; trace4("!oik", q1, qb, dqbdve, dqbdvc); }else{ double q2 = c->oik * cbe + c->oikr * cbc; double arg = std::max(0., 1+4*q2); double sqarg = (arg == 0.) ? 1 : sqrt(arg); qb = q1 * (1+sqarg) / 2; dqbdve = q1 * (qb * m->invearlyvoltr + c->oik * gbe / sqarg); dqbdvc = q1 * (qb * m->invearlyvoltf + c->oikr * gbc / sqarg); trace2("", c->oik, c->oikr); trace4("oik", q1, qb, dqbdve, dqbdvc); } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // weil's approx. for excess phase applied with backward-euler integration { double cc = 0.; double cex = cbe; double gex = gbe; if (0 && m->excessphasefactor != 0.) { unreachable(); incomplete(); // doesn't save old values of cexbc, so disabled double arg1 = d->_dt_0 / m->excessphasefactor; double arg2 = 3 * arg1; arg1 *= arg2; double denom = 1 + arg1 + arg2; double arg3 = arg1 / denom; if (_sim->is_initial_step()) { d->cexbc_2 = d->cexbc_1 = cbe / qb; }else{ } cc = (d->cexbc_1 * (1 + d->_dt_0/d->_dt_1 + arg2) - d->cexbc_2 * d->_dt_0/d->_dt_1) / denom; cex *= arg3; gex *= arg3; } d->cexbc_0 = cc + cex / qb; d->cce = cc + (cex-cbc)/qb - cbc/t->BetaR - cbcn; d->go = (gbc + (cex-cbc)*dqbdvc / qb) / qb; d->gm = (gex - (cex-cbc)*dqbdve / qb) / qb - d->go; d->ccexxx = d->cce - ((d->vbe - d->vbc) * d->go + d->vbe * d->gm); trace4("", d->cce, d->go, d->gm, d->cce/t->vt); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // d->gx // should be moved to a private eval // may use d->cpi, d->cmu, qb { if (!OPT::rstray || (!has_nz_value(m->rb) && !has_nz_value(m->rbm))) { trace3("", m->rb, m->irb, d->gx); assert(d->gx == NA); }else{ double rx = NA; double rbpr = m->rbm / c->area; double rbpi = m->rb / c->area - rbpr; if (has_nz_value(m->irb)) {itested();//554 // base resistance lowering at high current double cb = d->cpi + d->cmu; double xjrb = m->irb * c->area; double arg1 = std::max(cb/xjrb, 1e-9); double arg2 = (-1 + sqrt(1+14.59025*arg1)) / 2.4317 / sqrt(arg1); arg1 = tan(arg2); rx = rbpr + 3 * rbpi * (arg1-arg2) / arg2 / arg1 / arg1; }else{ rx = rbpr + rbpi / qb; } trace3("", m->rb, m->irb, rx); assert(rx != NA); assert(rx != 0.); d->gx = 1 / rx; trace1("", d->gx); } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const bool charge_computation_needed = OPT::cstray; if (charge_computation_needed) { if (has_nz_value(m->tf) && d->vbe > 0.) { double argtf = NA; double arg2 = NA; double arg3 = NA; if (has_nz_value(m->xtf)) {itested();//579 if (m->transtimevbcfact != 0.) { argtf = m->xtf * exp(d->vbc * m->transtimevbcfact); }else{untested(); argtf = m->xtf; } arg2 = argtf; if(has_nz_value(m->itf)) { double temp = cbe / (cbe + m->itf * c->area); argtf *= temp*temp; arg2 *= (3-temp-temp); }else{ } arg3 = cbe * argtf * m->transtimevbcfact; }else{ arg3 = arg2 = argtf = 0.; } assert(argtf != NA); assert(arg2 != NA); assert(arg3 != NA); cbe *= (1+argtf) / qb; gbe = (gbe * (1+arg2) - cbe * dqbdve) / qb; d->geqcb=m->tf*(arg3-cbe*dqbdvc)/qb; }else{ d->geqcb=0.; } { // d->qbe, d->cqbe // uses: d->vbe, cbe, gbe double czbe = t->BEcap * c->area; if (d->vbe < t->DepCap) { double arg = 1 - d->vbe / t->BEpot; double sarg = pow(arg, -m->mje); d->qbe = m->tf * cbe + t->BEpot * czbe * (1-arg*sarg) / (1 - m->mje); d->cqbe = m->tf * gbe + czbe * sarg; }else{ double czbef2 = czbe / m->f2; d->qbe = m->tf * cbe + czbe * t->f1 + czbef2 * (m->f3 * (d->vbe - t->DepCap) + (m->mje / (2. * t->BEpot)) * (d->vbe * d->vbe - t->DepCap * t->DepCap)); d->cqbe = m->tf * gbe + czbef2 * (m->f3 + m->mje*d->vbe / t->BEpot); } } { // d->qbc, d->cqbc // uses: d->vbc, cbc, gbc double czbc = t->BCcap * c->area * m->xcjc; if (d->vbc < t->f4) { double arg = 1 - d->vbc / t->BCpot; double sarg = pow(arg, -m->mjc); d->qbc = m->tr *cbc + t->BCpot *czbc * (1 - arg*sarg) / (1 - m->mjc); d->cqbc = m->tr * gbc + czbc * sarg; }else{ double czbcf2 = czbc / m->f6; d->qbc = m->tr * cbc + czbc * t->f5 + czbcf2 * (m->f7 * (d->vbc-t->f4) + (m->mjc/(t->BCpot+t->BCpot)) * (d->vbc*d->vbc-t->f4*t->f4)); d->cqbc = m->tr * gbc + czbcf2 * (m->f7 + m->mjc * d->vbc/t->BCpot); } } { // d->qbx, d->cqbx // uses: d->vbx double czbx = t->BCcap * c->area * (1 - m->xcjc); if (d->vbx < t->f4) { double arg = 1 - d->vbx / t->BCpot; double sarg = pow(arg, -m->mjc); d->qbx = t->BCpot * czbx * (1 - arg*sarg) / (1 - m->mjc); d->cqbx = czbx * sarg; }else{ double czbxf2 = czbx / m->f6; d->qbx = czbx * t->f5 + czbxf2 * (m->f7 * (d->vbx-t->f4) + (m->mjc / (t->BCpot+t->BCpot)) * (d->vbx*d->vbx-t->f4*t->f4)); d->cqbx = czbxf2 * (m->f7 + m->mjc * d->vbx / t->BCpot); } } { // d->qcs, d->cqcs // uses: d->vcs double czcs = m->cjs * c->area; if (d->vcs < 0.) { double arg = 1 - d->vcs / m->vjs; double sarg = pow(arg, -m->mjs); d->qcs = m->vjs * czcs * (1 - arg*sarg) / (1 - m->mjs); d->cqcs = czcs * sarg; }else{ d->qcs = d->vcs * czcs * (1 + m->mjs * d->vcs / (2 * m->vjs)); d->cqcs = czcs * (1 + m->mjs * d->vcs / m->vjs); } } } } } /*--------------------------------------------------------------------------*/ cc_direct { /*--------------------------------------------------------------------------*/ bool DEV_BUILT_IN_BJT::tr_needs_eval()const { if (is_q_for_eval()) { untested(); return false; }else if (!converged()) { return true; }else{ const COMMON_BUILT_IN_BJT* c = prechecked_cast(common()); assert(c); const MODEL_BUILT_IN_BJT* m=prechecked_cast(c->model()); assert(m); polarity_t polarity = m->polarity; return !(conchk(vbc, polarity*(_n[n_ib].v0()-_n[n_ic].v0()), OPT::vntol) && conchk(vbe, polarity*(_n[n_ib].v0()-_n[n_ie].v0()), OPT::vntol) && conchk(vcs, polarity*(_n[n_ic].v0()-_n[n_s].v0()), OPT::vntol)); } } /*--------------------------------------------------------------------------*/ bool DEV_BUILT_IN_BJT::do_tr() { const COMMON_BUILT_IN_BJT* c = prechecked_cast(common()); assert(c); const MODEL_BUILT_IN_BJT* m = prechecked_cast(c->model()); assert(m); const TDP_BUILT_IN_BJT T(this); const TDP_BUILT_IN_BJT* t = &T; if(_sim->is_initial_step()) { // initial guess if (c->off) { vbe = 0.; }else{ double vt = (_sim->_temp_c + P_CELSIUS0) * P_K_Q; vbe = vt * log(vt / (M_SQRT2 * m->ibe)); } vbc = 0.; /* ERROR: need to initialize VCS, VBX here */ vcs = vbx = 0.; }else{ // normal gather vbe = pnj_limit((m->polarity * volts_limited(_n[n_ib], _n[n_ie])), vbe, t->vt, t->Vcrit); vbc = pnj_limit((m->polarity * volts_limited(_n[n_ib], _n[n_ic])), vbc, t->vt, t->Vcrit); vbx = m->polarity * volts_limited(_n[n_b], _n[n_ic]); vcs = m->polarity * volts_limited(_n[n_s], _n[n_ic]); } if (_sim->uic_now()) {itested();//736 if (has_good_value(c->icvbe)) {untested();//737 vbe = m->polarity * c->icvbe; }else{itested();//739 } if (has_good_value(c->icvce)) {untested();//741 vbc = vbe - m->polarity * c->icvce; vbx = vbc; }else{itested();//744 } }else{ } m->tr_eval(this); switch (m->polarity) { case pP: cce = -cce; ccexxx = -ccexxx; cpi = -cpi; cpixxx = -cpixxx; cmu = -cmu; cmuxxx = -cmuxxx; assert(ixxxx == 0.); qbx = -qbx; qbc = -qbc; qcs = -qcs; qbe = -qbe; break; case pN: // leave it as is break; } assert(subckt()); set_converged(subckt()->do_tr()); return converged(); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_cap.cc����������������������������������������������������������������������������������������0000664�0000000�0000000�00000017615�11454012162�0013230�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_cap.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * capacitance devices: * self-capacitance (C device) * trans-capacitance (non-spice charge transfer device) *------------------------------------------------------------------ * capacitor models * y.x = volts, y.f0 = coulombs, ev = y.f1 = farads * q = y history in time * i.x = volts, i.f0 = amps, i.f1 = mhos * m.x = volts, m.c0 = amps, acg = m.c1 = mhos */ //testing=script 2006.07.17 #include "e_storag.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class DEV_CAPACITANCE : public STORAGE { protected: explicit DEV_CAPACITANCE(const DEV_CAPACITANCE& p) :STORAGE(p) {} public: explicit DEV_CAPACITANCE() :STORAGE() {} protected: // override virtual char id_letter()const {return 'C';} std::string value_name()const {return "c";} std::string dev_type()const {return "capacitor";} int max_nodes()const {return 2;} int min_nodes()const {return 2;} int matrix_nodes()const {return 2;} int net_nodes()const {return 2;} bool has_iv_probe()const {return true;} bool use_obsolete_callback_parse()const {return true;} CARD* clone()const {return new DEV_CAPACITANCE(*this);} void tr_iwant_matrix() {tr_iwant_matrix_passive();} bool do_tr(); void tr_load() {tr_load_passive();} void tr_unload() {tr_unload_passive();} double tr_involts()const {return tr_outvolts();} double tr_involts_limited()const {return tr_outvolts_limited();} double tr_probe_num(const std::string&)const; void ac_iwant_matrix() {ac_iwant_matrix_passive();} void ac_begin() {_ev = _y[0].f1;} void do_ac(); void ac_load() {ac_load_passive();} COMPLEX ac_involts()const {itested();return ac_outvolts();} std::string port_name(int i)const { assert(i >= 0); assert(i < 2); static std::string names[] = {"p", "n"}; return names[i]; } }; /*--------------------------------------------------------------------------*/ class DEV_TRANSCAP : public DEV_CAPACITANCE { private: explicit DEV_TRANSCAP(const DEV_TRANSCAP& p) :DEV_CAPACITANCE(p){} public: explicit DEV_TRANSCAP() :DEV_CAPACITANCE() {} private: // override virtual char id_letter()const {untested();return '\0';} std::string value_name()const {untested(); return "c";} std::string dev_type()const {return "tcap";} int max_nodes()const {return 4;} int min_nodes()const {return 4;} int matrix_nodes()const {return 4;} int net_nodes()const {return 4;} bool has_iv_probe()const {untested(); return false;} bool f_is_value()const {untested();return true;} CARD* clone()const {return new DEV_TRANSCAP(*this);} void tr_iwant_matrix() {tr_iwant_matrix_active();} void tr_load() {tr_load_active();} double tr_involts()const {return dn_diff(_n[IN1].v0(),_n[IN2].v0());} double tr_involts_limited()const {return volts_limited(_n[IN1],_n[IN2]);} void ac_iwant_matrix() {ac_iwant_matrix_active();} void ac_load() {untested(); ac_load_active();} std::string port_name(int i)const {untested(); assert(i >= 0); assert(i < 4); static std::string names[] = {"p", "n", "ps", "ns"}; return names[i]; } }; /*--------------------------------------------------------------------------*/ //BUG// doesn't model dynamic effects of control. class DEV_VCCAP : public DEV_CAPACITANCE { private: explicit DEV_VCCAP(const DEV_VCCAP& p) :DEV_CAPACITANCE(p) {} public: explicit DEV_VCCAP() :DEV_CAPACITANCE() {} private: // override virtual char id_letter()const {untested();return '\0';} std::string value_name()const {untested(); return "c";} std::string dev_type()const {return "vccap";} int max_nodes()const {return 4;} int min_nodes()const {return 4;} int matrix_nodes()const {return 4;} int net_nodes()const {return 4;} bool has_iv_probe()const {untested(); return false;} bool f_is_value()const {untested();return true;} CARD* clone()const {return new DEV_VCCAP(*this);} void tr_iwant_matrix() {tr_iwant_matrix_extended();} bool do_tr(); double tr_involts()const {return dn_diff(_n[IN1].v0(),_n[IN2].v0());} double tr_involts_limited()const {return volts_limited(_n[IN1],_n[IN2]);} void ac_iwant_matrix() {ac_iwant_matrix_extended();} std::string port_name(int i)const {untested(); assert(i >= 0); assert(i < 4); static std::string names[] = {"p", "n", "ps", "ns"}; return names[i]; } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ bool DEV_CAPACITANCE::do_tr() { if (using_tr_eval()) { _y[0].x = tr_input_limited(); tr_eval(); }else{ _y[0].x = tr_input(); // tr_involts(); assert(_y[0].f1 == value()); _y[0].f0 = _y[0].x * _y[0].f1; assert(converged()); } store_values(); q_load(); trace3("q", _y[0].x, _y[0].f0, _y[0].f1); _i[0] = differentiate(_y, _i, _time, _method_a); trace3("i", _i[0].x, _i[0].f0, _i[0].f1); _m0 = CPOLY1(_i[0]); return converged(); } /*--------------------------------------------------------------------------*/ void DEV_CAPACITANCE::do_ac() { if (using_ac_eval()) { ac_eval(); }else{ assert(_ev == _y[0].f1); assert(has_tr_eval() || _ev == double(value())); } _acg = _ev * _sim->_jomega; } /*--------------------------------------------------------------------------*/ double DEV_CAPACITANCE::tr_probe_num(const std::string& x)const { if (Umatch(x, "q{cap} |ch{arge} ")) { return _y[0].f0; }else if (Umatch(x, "c{apacitance} ")) { return _y[0].f1; }else if (Umatch(x, "dcdt ")) {untested(); return (_y[0].f1 - _y[1].f1) / _dt; }else if (Umatch(x, "dc ")) {untested(); return (_y[0].f1 - _y[1].f1); }else if (Umatch(x, "dqdt ")) { return (_y[0].f0 - _y[1].f0) / _dt; }else if (Umatch(x, "dq ")) { return (_y[0].f0 - _y[1].f0); }else{ return STORAGE::tr_probe_num(x); } } /*--------------------------------------------------------------------------*/ bool DEV_VCCAP::do_tr() { _y[0].x = tr_input_limited(); tr_eval(); store_values(); q_load(); _y[0].x = tr_outvolts(); _y[0].f1 = _y[0].f0; // self capacitance _y[0].f0 = _y[0].x * _y[0].f1; // charge _i[0] = differentiate(_y, _i, _time, _method_a); _m0.x = _i[0].x; _m0.c1 = _i[0].f1; _m0.c0 = _i[0].f0 - _i[0].x * _i[0].f1; return converged(); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_CAPACITANCE p1; DEV_TRANSCAP p2; DEV_VCCAP p3; DISPATCHER::INSTALL d1(&device_dispatcher, "C|capacitor", &p1), d2(&device_dispatcher, "tcap|tcapacitor", &p2), d3(&device_dispatcher, "vccap", &p3); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������������������������src/d_cccs.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000011670�11454012162�0013373�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_cccs.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * functions for cccs * It is really voltage controlled, taking into account the sense element. * Then adjust the gain to account for the sense element. */ //testing=script,complete 2008.10.09 #include "e_ccsrc.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class DEV_CCCS : public CCSRC_BASE { private: explicit DEV_CCCS(const DEV_CCCS& p) :CCSRC_BASE(p) {} public: explicit DEV_CCCS() :CCSRC_BASE() {} private: // override virtual char id_letter()const {return 'F';} std::string value_name()const {return "gain";} std::string dev_type()const {return "cccs";} bool use_obsolete_callback_parse()const {return true;} CARD* clone()const {return new DEV_CCCS(*this);} void precalc_last(); void tr_iwant_matrix() {tr_iwant_matrix_active();} void tr_begin(); bool do_tr() {_sim->_late_evalq.push_back(this); return true;} bool do_tr_last(); void tr_load() {tr_load_active();} void ac_iwant_matrix() {ac_iwant_matrix_active();} void ac_begin() {_ev = _y[0].f1;} void do_ac(); void ac_load() {ac_load_active();} std::string port_name(int i)const {untested(); assert(i >= 0); assert(i < 2); static std::string names[] = {"sink", "src"}; return names[i]; } std::string current_port_name(int i)const {untested(); assert(i >= 0); assert(i < 1); static std::string names[] = {"in"}; return names[i]; } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void DEV_CCCS::precalc_last() { CCSRC_BASE::precalc_last(); set_converged(); assert(!is_constant()); /* because of incomplete analysis */ } /*--------------------------------------------------------------------------*/ void DEV_CCCS::tr_begin() { CCSRC_BASE::tr_begin(); _m0.x = _y[0].x; _m0.c1 = _y[0].f1; _m0.c0 = 0.; _m1 = _m0; assert(_loss0 == 0.); assert(_loss1 == 0.); } /*--------------------------------------------------------------------------*/ bool DEV_CCCS::do_tr_last() { assert(_input); if (using_tr_eval()) { _m0.x = tr_involts_limited(); _y[0].x = tr_input_limited(); tr_eval(); assert(_y[0].f0 != LINEAR); _m0 = CPOLY1(_y[0]); }else{ assert(_y[0].f0 == LINEAR); assert(_y[0].f1 == value()); _m0.c0 = 0.; assert(converged()); } if (_input->has_inode()) {untested(); // nothing }else if (_input->has_iv_probe()) { _m0.c0 += _y[0].f1 * _input->_m0.c0; _m0.c1 = _y[0].f1 * (_input->_loss0 + _input->_m0.c1); }else{unreachable(); } store_values(); q_load(); return converged(); } /*--------------------------------------------------------------------------*/ void DEV_CCCS::do_ac() { assert(_input); if (!_input->evaluated()) { /* patch for forward reference */ ELEMENT* input = const_cast(_input); input->do_ac(); /* make sure sense elt is evaluated first */ }else{ } if (using_ac_eval()) { ac_eval(); }else{ assert(_ev == _y[0].f1); assert(has_tr_eval() || _ev == double(value())); } if (_input->is_source()) { /* if the sense elt is a fixed source.. */ _acg = _ev * _input->_acg; /* then part of this one can be modeled */ ac_load_source(); /* as a fixed source. ... */ _acg = _ev * _input->_loss0;/* so load it in 2 pieces */ }else if (_input->has_inode()) {untested(); _acg = _ev; }else if (_input->has_iv_probe()) { _acg = _ev * _input->_acg; }else{unreachable(); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_CCCS p1; DISPATCHER::INSTALL d1(&device_dispatcher, "F|cccs", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ������������������������������������������������������������������������src/d_ccvs.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000011732�11454012162�0013415�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_ccvs.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * functions for ccvs * It is really voltage controlled, taking into account the sense element. * Then adjust the gain to account for the sense element. */ //testing=script 2006.07.17 #include "e_ccsrc.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class DEV_CCVS : public CCSRC_BASE { private: explicit DEV_CCVS(const DEV_CCVS& p) :CCSRC_BASE(p) {} public: explicit DEV_CCVS() :CCSRC_BASE() {} private: // override virtual char id_letter()const {return 'H';} std::string value_name()const {untested(); return "gain";} std::string dev_type()const {return "ccvs";} bool use_obsolete_callback_parse()const {return true;} CARD* clone()const {return new DEV_CCVS(*this);} void precalc_last(); void tr_iwant_matrix() {tr_iwant_matrix_extended();} void tr_begin(); bool do_tr() {_sim->_late_evalq.push_back(this); return true;} bool do_tr_last(); void tr_load() {tr_load_shunt(); tr_load_active();} void ac_iwant_matrix() {ac_iwant_matrix_extended();} void ac_begin() {_loss1=_loss0=1./OPT::shortckt; _ev = _y[0].f1;} void do_ac(); void ac_load() {ac_load_active();} COMPLEX ac_amps()const {untested(); return ELEMENT::ac_amps();} std::string port_name(int i)const {untested(); assert(i >= 0); assert(i < 2); static std::string names[] = {"p", "n"}; return names[i]; } std::string current_port_name(int i)const {untested(); assert(i >= 0); assert(i < 1); static std::string names[] = {"in"}; return names[i]; } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void DEV_CCVS::precalc_last() { CCSRC_BASE::precalc_last(); set_converged(); assert(!is_constant()); /* because of incomplete analysis */ } /*--------------------------------------------------------------------------*/ void DEV_CCVS::tr_begin() { CCSRC_BASE::tr_begin(); _loss1 = _loss0 = 1./OPT::shortckt; _m0.x = _y[0].x; _m0.c1 = -_loss0 * value(); _m0.c0 = 0.; _m1 = _m0; } /*--------------------------------------------------------------------------*/ bool DEV_CCVS::do_tr_last() { assert(_input); if (using_tr_eval()) { _m0.x = tr_involts_limited(); _y[0].x = tr_input_limited(); tr_eval(); assert(_y[0].f0 != LINEAR); _m0 = CPOLY1(_y[0]); }else{ assert(_y[0].f0 == LINEAR); assert(_y[0].f1 == value()); _m0.c0 = 0.; assert(converged()); } if (_input->has_inode()) {untested(); // nothing }else if (_input->has_iv_probe()) { _m0.c0 += _y[0].f1 * _input->_m0.c0; _m0.c1 = _y[0].f1 * (_input->_loss0 + _input->_m0.c1); }else{unreachable(); } _m0 *= -_loss0; store_values(); q_load(); return converged(); } /*--------------------------------------------------------------------------*/ void DEV_CCVS::do_ac() { assert(_input); if (!_input->evaluated()) {untested(); ELEMENT* input = const_cast(_input); input->do_ac(); //BUG// premature load of sense element }else{ } ac_load_shunt(); if (using_ac_eval()) {untested(); ac_eval(); }else{ assert(_ev == _y[0].f1); assert(has_tr_eval() || _ev == double(value())); } if (_input->is_source()) { _acg = -_loss0 * _ev * _input->_acg; ac_load_source(); _acg = -_loss0 * _ev * _input->_loss0; }else if (_input->has_inode()) {untested(); _acg = -_loss0 * _ev; }else if (_input->has_iv_probe()) { _acg = -_loss0 * _ev * _input->_acg; }else{unreachable(); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_CCVS p1; DISPATCHER::INSTALL d1(&device_dispatcher, "H|ccvs", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������src/d_coil.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000043261�11454012162�0013407�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_coil.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * inductors * y.x = amps, y.f0 = flux, ev = y.f1 = henrys * q = y history in time * i.x = amps, i.f0 = volts, i.f1 = ohms * m.x = volts, m.c0 = amps, acg = m.c1 = mhos */ //testing=script 2008.10.09 #include "e_subckt.h" #include "e_ccsrc.h" #include "e_storag.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class DEV_INDUCTANCE : public STORAGE { protected: explicit DEV_INDUCTANCE(const DEV_INDUCTANCE& p) :STORAGE(p), _c_model(p._c_model) {} public: explicit DEV_INDUCTANCE() :STORAGE(), _c_model(false) {} public: // override virtual char id_letter()const {return 'L';} std::string value_name()const {return "l";} std::string dev_type()const {return "inductor";} int max_nodes()const {return 2;} int min_nodes()const {return 2;} int net_nodes()const {return 2;} int int_nodes()const {return (!_c_model) ? 0 : 1;} int matrix_nodes()const {return net_nodes() + int_nodes();} bool has_inode()const {return _c_model;} bool has_iv_probe()const {return true;} bool use_obsolete_callback_parse()const {return true;} CARD* clone()const {return new DEV_INDUCTANCE(*this);} void expand(); void tr_iwant_matrix(); void tr_begin(); bool do_tr(); void tr_load(); void tr_unload(); double tr_involts()const {return tr_outvolts();} double tr_input()const; double tr_involts_limited()const {return tr_outvolts_limited();} double tr_input_limited()const; double tr_amps()const; double tr_probe_num(const std::string&)const; void ac_iwant_matrix(); void ac_begin() {_loss1 = _loss0 = ((!_c_model) ? 0. : 1.); _ev = _y[0].f1;} void do_ac(); void ac_load(); COMPLEX ac_involts()const {return ac_outvolts();} COMPLEX ac_amps()const; std::string port_name(int i)const {itested(); assert(i >= 0); assert(i < 2); static std::string names[] = {"p", "n"}; return names[i]; } bool _c_model; }; /*--------------------------------------------------------------------------*/ class DEV_MUTUAL_L : public DEV_INDUCTANCE { private: std::string _output_label; DEV_INDUCTANCE* _output; std::string _input_label; DEV_INDUCTANCE* _input; double _lm; double _mf0_c0; // matrix parameters, new double _mf1_c0; // matrix parameters, 1 fill ago double _mr0_c0; // matrix parameters, new double _mr1_c0; // matrix parameters, 1 fill ago FPOLY1 _yf1; // iteration parameters, 1 iter ago FPOLY1 _yf[OPT::_keep_time_steps]; FPOLY1 _if[OPT::_keep_time_steps]; FPOLY1 _yr1; // iteration parameters, 1 iter ago FPOLY1 _yr[OPT::_keep_time_steps]; FPOLY1 _ir[OPT::_keep_time_steps]; private: explicit DEV_MUTUAL_L(const DEV_MUTUAL_L& p); public: explicit DEV_MUTUAL_L(); private: // override virtual char id_letter()const {return 'K';} bool print_type_in_spice()const {return false;} std::string value_name()const {return "k";} std::string dev_type()const {untested(); return "mutual_inductor";} int max_nodes()const {return 2;} int min_nodes()const {return 2;} int matrix_nodes()const {return 2;} int net_nodes()const {return 0;} int num_current_ports()const {return 2;} bool has_iv_probe()const {untested(); return false;} bool use_obsolete_callback_parse()const {return false;} CARD* clone()const {return new DEV_MUTUAL_L(*this);} void expand_first(); void expand_last(); void precalc_last(); void tr_iwant_matrix() {tr_iwant_matrix_passive();} void tr_begin(); void dc_advance(); void tr_advance(); bool do_tr() {_sim->_late_evalq.push_back(this); return true;} bool do_tr_last(); void tr_load(); TIME_PAIR tr_review() {return TIME_PAIR(NEVER,NEVER);} void tr_unload(); double tr_input()const {return tr_involts();} double tr_input_limited()const {untested(); return tr_involts_limited();} double tr_amps()const {untested(); return _loss0 * tr_outvolts();} double tr_probe_num(const std::string&)const; void ac_iwant_matrix() {ac_iwant_matrix_passive();} void ac_load(); COMPLEX ac_amps()const {untested(); return _loss0 * ac_outvolts();} void set_port_by_name(std::string& Name, std::string& Value) {untested(); COMPONENT::set_port_by_name(Name,Value);} void set_port_by_index(int Index, std::string& Value) {set_current_port_by_index(Index, Value);} bool node_is_connected(int i)const { switch (i) { case 0: return _output_label != ""; case 1: return _input_label != ""; default: unreachable(); return false; } } std::string port_name(int)const {untested(); return ""; } std::string current_port_name(int i)const {untested(); assert(i >= 0); assert(i < 2); static std::string names[] = {"l1", "l2"}; return names[i]; } const std::string current_port_value(int i)const { switch (i) { case 0: return _output_label; case 1: return _input_label; default: unreachable(); return COMPONENT::current_port_value(i); } } void set_current_port_by_index(int i, const std::string& s) { switch (i) { case 0: _output_label = s; break; case 1: _input_label = s; break; default: unreachable(); break; } } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_MUTUAL_L::DEV_MUTUAL_L() :DEV_INDUCTANCE(), _output_label(), _output(0), _input_label(), _input(0), _lm(NOT_INPUT), _mf0_c0(0.), _mf1_c0(0.), _mr0_c0(0.), _mr1_c0(0.) { _c_model = true; assert(_yf[0].x == 0. && _yf[0].f0 == 0. && _yf[0].f1 == 0.); assert(_yf1 == _yf[0]); assert(_yr[0].x == 0. && _yr[0].f0 == 0. && _yr[0].f1 == 0.); assert(_yr1 == _yr[0]); } /*--------------------------------------------------------------------------*/ DEV_MUTUAL_L::DEV_MUTUAL_L(const DEV_MUTUAL_L& p) :DEV_INDUCTANCE(p), _output_label(p._output_label), _output(p._output), _input_label(p._input_label), _input(p._input), _lm(p._lm), _mf0_c0(0.), _mf1_c0(0.), _mr0_c0(0.), _mr1_c0(0.) { _c_model = true; assert(_yf[0].x == 0. && _yf[0].f0 == 0. && _yf[0].f1 == 0.); assert(_yf1 == _yf[0]); assert(_yr[0].x == 0. && _yr[0].f0 == 0. && _yr[0].f1 == 0.); assert(_yr1 == _yr[0]); } /*--------------------------------------------------------------------------*/ void DEV_INDUCTANCE::expand() { STORAGE::expand(); if (_sim->is_first_expand()) { if (!_c_model) { _n[IN1].set_to_ground(this); }else{ _n[IN1].new_model_node(long_label() + ".i", this); } }else{untested(); } } /*--------------------------------------------------------------------------*/ void DEV_MUTUAL_L::expand_first() { _output = dynamic_cast(find_in_my_scope(_output_label)); if (!_output) { throw Exception_Type_Mismatch(long_label(), _output_label, "inductor"); }else{ _output->_c_model = true; } _input = dynamic_cast(find_in_my_scope(_input_label)); if (!_input) { throw Exception_Type_Mismatch(long_label(), _input_label, "inductor"); }else{ _input->_c_model = true; } } /*--------------------------------------------------------------------------*/ void DEV_MUTUAL_L::expand_last() { STORAGE::expand(); // skip DEV_INDUCTANCE if (_sim->is_first_expand()) { _n[OUT2] = _input->n_(IN1); _n[OUT1] = _output->n_(IN1); }else{untested(); } } /*--------------------------------------------------------------------------*/ void DEV_MUTUAL_L::precalc_last() { _output->precalc_last(); _input->precalc_last(); DEV_INDUCTANCE::precalc_last(); double l1 = _output->value(); double l2 = _input->value(); _lm = value() * sqrt(l1 * l2); trace3(long_label().c_str(), l1, l2, _lm); if (_sim->is_first_expand()) { assert(_y[0].x == 0.); assert(_y[0].f0 == LINEAR); _y[0].f1 = -_lm; // override _yf[0] = _yr[0] = _y[0]; }else{ } } /*--------------------------------------------------------------------------*/ void DEV_INDUCTANCE::tr_iwant_matrix() { if (!_c_model) { tr_iwant_matrix_passive(); }else{ assert(matrix_nodes() == 3); assert(_n[OUT1].m_() != INVALID_NODE); assert(_n[OUT2].m_() != INVALID_NODE); assert(_n[IN1].m_() != INVALID_NODE); _sim->_aa.iwant(_n[OUT1].m_(),_n[IN1].m_()); _sim->_aa.iwant(_n[OUT2].m_(),_n[IN1].m_()); _sim->_lu.iwant(_n[OUT1].m_(),_n[IN1].m_()); _sim->_lu.iwant(_n[OUT2].m_(),_n[IN1].m_()); } } /*--------------------------------------------------------------------------*/ void DEV_INDUCTANCE::tr_begin() { STORAGE::tr_begin(); _loss1 = _loss0 = ((!_c_model) ? 0. : 1.); } /*--------------------------------------------------------------------------*/ void DEV_MUTUAL_L::tr_begin() { DEV_INDUCTANCE::tr_begin(); assert(_y[0].x == 0.); assert(_y[0].f0 == LINEAR); _y[0].f1 = -_lm; // override _y1 = _y[0]; for (int i = 0; i < OPT::_keep_time_steps; ++i) { _if[i] = _ir[i] = FPOLY1(0., 0., 0.); } _mf1_c0 = _mf0_c0 = _mr1_c0 = _mr0_c0 = 0.; } /*--------------------------------------------------------------------------*/ void DEV_MUTUAL_L::dc_advance() { STORAGE::dc_advance(); for (int i = 1; i < OPT::_keep_time_steps; ++i) { _if[i] = _if[0]; _ir[i] = _ir[0]; } } /*--------------------------------------------------------------------------*/ void DEV_MUTUAL_L::tr_advance() { STORAGE::tr_advance(); for (int i=OPT::_keep_time_steps-1; i>0; --i) { _yf[i] = _yf[i-1]; _yr[i] = _yr[i-1]; _if[i] = _if[i-1]; _ir[i] = _ir[i-1]; } } /*--------------------------------------------------------------------------*/ bool DEV_INDUCTANCE::do_tr() { if (using_tr_eval()) { _y[0].x = tr_input_limited(); // _m0.c0 + _m0.c1 * x; tr_eval(); if ((!_c_model) && (_y[0].f1 == 0.)) {untested(); error(bDANGER, long_label() + ": short circuit, L = 0\n"); _y[0].f1 = OPT::shortckt; set_converged(conv_check()); }else{ } }else{ _y[0].x = tr_input(); // _m0.c0 + _m0.c1 * x; assert(_y[0].f1 == value()); _y[0].f0 = _y[0].x * _y[0].f1; assert(converged()); } store_values(); q_load(); // i is really voltage .. // _i[0].x = current, _i[0].f0 = voltage, _i[0].f1 = ohms _i[0] = differentiate(_y, _i, _time, _method_a); if (!_c_model) { _m0.x = NOT_VALID; _m0.c1 = 1 / ((_i[0].c1()==0) ? OPT::shortckt : _i[0].c1()); _m0.c0 = -_i[0].c0() * _m0.c1; }else{ //_m0 = -CPOLY1(_i[0]); _m0.x = NOT_VALID; _m0.c1 = -_loss0 * _loss0 * _i[0].c1(); _m0.c0 = _loss0 * _loss0 * _i[0].c0(); } return converged(); } /*--------------------------------------------------------------------------*/ bool DEV_MUTUAL_L::do_tr_last() { double l1 = _output->_y[0].f1; double l2 = _input->_y[0].f1; _lm = value() * sqrt(l1 * l2); _y[0].x = _n[OUT1].v0() - _n[OUT2].v0(); // really current _y[0].f1 = -_lm; _y[0].f0 = _y[0].x * _y[0].f1; // flux = I * L trace3("", _y[0].x, _y[0].f0, _y[0].f1); store_values(); _i[0] = differentiate(_y, _i, _time, _method_a); // really voltage, v = df/dt trace3("", _i[0].x, _i[0].f0, _i[0].f1); _m0.x = NOT_VALID; _m0.c1 = -_loss0 * _loss0 * _i[0].c1(); _m0.c0 = -_loss0 * _loss0 * _i[0].c0(); trace3("", _m0.x, _m0.c0, _m0.c1); _yf[0].x = _n[OUT1].v0(); _yf[0].f1 = -_lm; _yf[0].f0 = _yf[0].x * _yf[0].f1; trace3("", _yf[0].x, _yf[0].f0, _yf[0].f1); assert(_yf[0]==_yf[0]); // store_values(); _yf1=_yf[0]; // store_values(); _if[0] = differentiate(_yf, _if, _time, _method_a); trace3("", _if[0].x, _if[0].f0, _if[0].f1); _mf0_c0 = -_loss0 * _loss0 * _if[0].c0(); _yr[0].x = _n[OUT2].v0(); _yr[0].f1 = -_lm; _yr[0].f0 = _yr[0].x * _yr[0].f1; trace3("", _yr[0].x, _yr[0].f0, _yr[0].f1); assert(_yr[0]==_yr[0]); // store_values(); _yr1=_yr[0]; // store_values(); _ir[0] = differentiate(_yr, _ir, _time, _method_a); trace3("", _ir[0].x, _ir[0].f0, _ir[0].f1); _mr0_c0 = -_loss0 * _loss0 * _ir[0].c0(); q_load(); return true; } /*--------------------------------------------------------------------------*/ void DEV_INDUCTANCE::tr_load() { if (!_c_model) { tr_load_passive(); }else{ tr_load_inode(); tr_load_diagonal_point(_n[IN1], &_m0.c1, &_m1.c1); tr_load_source_point(_n[IN1], &_m0.c0, &_m1.c0); } } /*--------------------------------------------------------------------------*/ void DEV_MUTUAL_L::tr_load() { tr_load_couple(); tr_load_source(); tr_load_source_point(_n[OUT2], &_mr0_c0, &_mr1_c0); tr_load_source_point(_n[OUT1], &_mf0_c0, &_mf1_c0); } /*--------------------------------------------------------------------------*/ void DEV_INDUCTANCE::tr_unload() {untested(); _loss0 = _m0.c0 = _m0.c1 = 0.; _sim->mark_inc_mode_bad(); tr_load(); } /*--------------------------------------------------------------------------*/ void DEV_MUTUAL_L::tr_unload() {untested(); tr_unload_couple(); } /*--------------------------------------------------------------------------*/ double DEV_INDUCTANCE::tr_input()const { if (!_c_model) { return _m0.c0 + _m0.c1 * tr_involts(); }else{ return _n[IN1].v0(); } } /*--------------------------------------------------------------------------*/ double DEV_INDUCTANCE::tr_input_limited()const { if (!_c_model) { return _m0.c0 + _m0.c1 * tr_involts_limited(); }else{ return _n[IN1].v0(); } } /*--------------------------------------------------------------------------*/ double DEV_INDUCTANCE::tr_amps()const { if (!_c_model) { return fixzero((_m0.c1 * tr_involts() + _m0.c0), _m0.c0); }else{ return _loss0 * _n[IN1].v0(); } } /*--------------------------------------------------------------------------*/ void DEV_INDUCTANCE::ac_iwant_matrix() { if (!_c_model) { ac_iwant_matrix_passive(); }else{ assert(matrix_nodes() == 3); assert(_n[OUT1].m_() != INVALID_NODE); assert(_n[OUT2].m_() != INVALID_NODE); assert(_n[IN1].m_() != INVALID_NODE); _sim->_acx.iwant(_n[OUT1].m_(),_n[IN1].m_()); _sim->_acx.iwant(_n[OUT2].m_(),_n[IN1].m_()); } } /*--------------------------------------------------------------------------*/ void DEV_INDUCTANCE::do_ac() { if (using_ac_eval()) { ac_eval(); }else{ assert(_ev == _y[0].f1); assert(dynamic_cast(this) || has_tr_eval() || _ev == double(value())); } if (!_c_model) { if (_ev * _sim->_jomega == 0.) {untested(); _acg = 1. / OPT::shortckt; }else{ _acg = 1. / (_ev * _sim->_jomega); } }else{ _acg = -_loss0 * _loss0 * _ev * _sim->_jomega; } } /*--------------------------------------------------------------------------*/ void DEV_INDUCTANCE::ac_load() { if (!_c_model) { ac_load_passive(); }else{ ac_load_inode(); ac_load_diagonal_point(_n[IN1], _acg); } } /*--------------------------------------------------------------------------*/ void DEV_MUTUAL_L::ac_load() { ac_load_couple(); } /*--------------------------------------------------------------------------*/ COMPLEX DEV_INDUCTANCE::ac_amps()const { if (!_c_model) { return (ac_involts() * _acg); }else{ return _loss0 * _n[IN1].vac(); } } /*--------------------------------------------------------------------------*/ double DEV_INDUCTANCE::tr_probe_num(const std::string& x)const { if (Umatch(x, "flux ")) {untested(); return _y[0].f0; }else if (Umatch(x, "ind{uctance} |l ")) {untested(); return _y[0].f1; }else if (Umatch(x, "dldt ")) {untested(); return (_y[0].f1 - _y[1].f1) / _dt; }else if (Umatch(x, "dl ")) {untested(); return (_y[0].f1 - _y[1].f1); }else if (Umatch(x, "dfdt ")) {untested(); return (_y[0].f0 - _y[1].f0) / _dt; }else if (Umatch(x, "dflux ")) {untested(); return (_y[0].f0 - _y[1].f0); }else{ return STORAGE::tr_probe_num(x); } } /*--------------------------------------------------------------------------*/ double DEV_MUTUAL_L::tr_probe_num(const std::string& x)const {untested(); if (Umatch(x, "fflux ")) {untested(); return _yf[0].f0; }else if (Umatch(x, "rflux ")) {untested(); return _yr[0].f0; }else if (Umatch(x, "fiof{fset} ")) {untested(); return _mf0_c0; }else if (Umatch(x, "riof{fset} ")) {untested(); return _mr0_c0; }else{untested(); return DEV_INDUCTANCE::tr_probe_num(x); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_MUTUAL_L p1; DEV_INDUCTANCE p2; DISPATCHER::INSTALL d1(&device_dispatcher, "K|mutual_inductor", &p1), d2(&device_dispatcher, "L|inductor", &p2); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_coment.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000003772�11454012162�0013613�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_coment.h,v 26.83 2008/06/05 04:46:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * processing for COMMENT netlist item (pseudo-device) */ //testing=script 2006.07.17 #include "e_card.h" /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ class DEV_COMMENT : public CARD { private: std::string _s; explicit DEV_COMMENT(const DEV_COMMENT& p) :CARD(p) {set_constant(true);} public: explicit DEV_COMMENT() :CARD() {set_constant(true);} private: // override virtual char id_letter()const {untested(); return '\0';} std::string dev_type()const {untested(); return "comment";} CARD* clone()const {return new DEV_COMMENT(*this);} std::string value_name()const {return "";} public: void set(const std::string& s) {_s = s;} std::string comment()const {return _s;} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ������src/d_cs.cc�����������������������������������������������������������������������������������������0000664�0000000�0000000�00000010524�11454012162�0013062�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_cs.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * functions for fixed current source * x = 0, y.f0 = nothing, ev = y.f1 = amps. */ //testing=script 2006.07.17 #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class DEV_CS : public ELEMENT { private: explicit DEV_CS(const DEV_CS& p) :ELEMENT(p) {} public: explicit DEV_CS() :ELEMENT() {} private: // override virtual char id_letter()const {return 'I';} std::string value_name()const {itested(); return "dc";} std::string dev_type()const {return "isource";} int max_nodes()const {return 2;} int min_nodes()const {return 2;} int matrix_nodes()const {return 2;} int net_nodes()const {return 2;} bool is_source()const {return true;} bool f_is_value()const {return true;} bool has_iv_probe()const {return true;} bool use_obsolete_callback_parse()const {return true;} CARD* clone()const {return new DEV_CS(*this);} void precalc_last(); void tr_iwant_matrix() {/* nothing */} void tr_begin(); bool do_tr(); void tr_load() {tr_load_source();} void tr_unload() {untested();tr_unload_source();} double tr_involts()const {return 0.;} double tr_involts_limited()const {unreachable(); return 0.;} void ac_iwant_matrix() {/* nothing */} void ac_begin() {_acg = _ev = 0.;} void do_ac(); void ac_load() {ac_load_source();} COMPLEX ac_involts()const {untested();return 0.;} COMPLEX ac_amps()const {return _acg;} std::string port_name(int i)const { assert(i >= 0); assert(i < 2); static std::string names[] = {"p", "n"}; return names[i]; } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void DEV_CS::precalc_last() { ELEMENT::precalc_last(); set_constant(!has_tr_eval()); set_converged(!has_tr_eval()); } /*--------------------------------------------------------------------------*/ void DEV_CS::tr_begin() { ELEMENT::tr_begin(); _y1.f0 = _y[0].f0 = 0.; // override _m0.x = 0.; _m0.c0 = _y[0].f1; _m0.c1 = 0.; _m1 = _m0; assert(_loss0 == 0.); assert(_loss1 == 0.); } /*--------------------------------------------------------------------------*/ bool DEV_CS::do_tr() { assert(_m0.x == 0.); if (using_tr_eval()) { _y[0].x = _sim->_time0; tr_eval(); store_values(); q_load(); _m0.c0 = _y[0].f1; assert(_m0.c1 == 0.); }else{untested(); assert(_y[0].x == 0.); assert(_y[0].f0 == 0.); assert(_y[0].f1 == value()); assert(_m0.x == 0.); assert(_m0.c0 == _y[0].f1); assert(_m0.c1 == 0.); assert(_y1 == _y[0]); assert(converged()); } return converged(); } /*--------------------------------------------------------------------------*/ void DEV_CS::do_ac() { if (using_ac_eval()) { ac_eval(); _acg = _ev; }else{untested(); assert(_acg == 0.); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_CS p1; DISPATCHER::INSTALL d1(&device_dispatcher, "I|csource|isource", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_diode.model�����������������������������������������������������������������������������������0000664�0000000�0000000�00000033157�11454012162�0014263�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: d_diode.model,v 26.132 2009/11/24 04:26:37 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * diode model. * netlist syntax: * device: dxxxx n+ n- mname * model: .model mname D * * The section "eval Yj" is a big mess. * It will be redone using multiple files, like the MOS models. */ h_headers { enum region_t {INITOFF=-2, REVERSE=-1, UNKNOWN=0, FORWARD=1}; enum polarity_t {pP = -1, pN = 1}; } cc_headers { #include "e_aux.h" #include "e_storag.h" static bool dummy=false; enum {USE_OPT = 0x8000}; } /*--------------------------------------------------------------------------*/ device BUILT_IN_DIODE { parse_name diode; model_type BUILT_IN_DIODE; id_letter D; circuit { ports {a c}; local_nodes { ia short_to=a short_if="!OPT::rstray || c->rs_adjusted==0."; } capacitor Cj {ia c} eval=Cj omit="c->cj_adjusted == 0. && c->cjsw_adjusted == 0. && m->tt == 0."; admittance Yj {ia c} eval=Yj; resistor Rs {a ia} value="c->rs_adjusted" omit="!OPT::rstray || c->rs_adjusted==0."; } tr_probe { "v{d}" = "@n_a[V] - @n_c[V]"; "i{d}" = "@Yj[I] + @Cj[I]"; vj = "@n_ia[V] - @n_c[V]" vsr = "@n_a[V] - @n_ia[V]" vrs = "@n_a[V] - @n_ia[V]" ij = "@Yj[I]"; ic = "@Cj[I]"; capcur = "@Cj[I]"; p = "@Yj[P] + @Cj[P] + @Rs[P]"; pd = "@Yj[PD] + @Cj[PD] + @Rs[PD]"; ps = "@Yj[PS] + @Cj[PS] + @Rs[PS]"; pj = "@Yj[P]"; pc = "@Cj[P]"; "c{apacitance}" = "@Cj[Capacitance]"; cd = "@Cj[Capacitance]"; charge = "@Cj[Charge]"; "r{eq}" = "@Yj[R] + @Rs[R]"; "g{eq}" = "((@Yj[R] + @Rs[R]) != 0) ? (1./(@Yj[R] + @Rs[R])) : @Yj[Y]"; gd = "@Yj[Y]"; y = "(@Rs[R] != 0. && (@Yj[Y] + @Cj[Y]) != 0) ? 1./((1./(@Yj[Y] + @Cj[Y])) + @Rs[R]) : @Yj[Y] + @Cj[Y]"; z = "port_impedance(@n_a[],@n_c[],_sim->_lu,mfactor()*tr_probe_num(\"Y\"))"; zraw = "port_impedance(@n_a[], @n_c[], _sim->_lu, 0.)"; region = "static_cast(_region)"; } device { calculated_parameters { region_t _region "fwd, reverse, unknown" default=UNKNOWN; double _gd "conductance to pass to capacitor"; double _isat "is adjusted for temp, etc."; } } common { unnamed area; raw_parameters { double area "area factor" name=Area default=1.0 positive; double perim "perimeter factor" name=Perim default=0.0 positive print_test="perim != 0."; bool off "flag: assume reverse biased" name=OFF default=false print_test=off; double ic "initial voltage" name=IC default=NA print_test="has_good_value(ic)"; double is_raw "saturation current" name=IS default=NA positive print_test="has_good_value(is_raw)"; double rs_raw "series resistance" name=Rs default=NA positive print_test="has_good_value(rs_raw)"; double cj_raw "zero bias jct capacitance" name=Cjo default=NA positive print_test="has_good_value(cj_raw)"; double cjsw_raw "zero bias sidewall capacitance" name=CJSW default=NA positive print_test="has_good_value(cjsw_raw)"; double gparallel_raw "parallel conductance" name=GParallel default=NA print_test="has_good_value(gparallel_raw)"; } calculated_parameters { double is_adjusted "" name = IS calculate="((!has_good_value(c->is_raw))?(m->js*c->area):(c->is_raw))" calc_print_test="is_adjusted != c->is_raw"; double rs_adjusted "" name = RS calculate="((!has_good_value(c->rs_raw)) ? (m->rs / (c->area+1e-20)) : (c->rs_raw))" calc_print_test="rs_adjusted != c->rs_raw"; double cj_adjusted "" name = CJ calculate="((!has_good_value(c->cj_raw))?(m->cjo*c->area):(c->cj_raw))" calc_print_test="cj_adjusted != c->cj_raw"; double cjsw_adjusted "" name = CJSW calculate="((!has_good_value(c->cjsw_raw)) ? (m->cjsw * c->perim) : (c->cjsw_raw))" calc_print_test="cjsw_adjusted != c->cjsw_raw"; double gparallel_adjusted "" name = GParallel calculate="((!has_good_value(c->gparallel_raw)) ? (m->gparallel*c->area) : (c->gparallel_raw))" print_test="gparallel_adjusted != c->gparallel_raw"; } } eval Cj { double& volts = d->_y[0].x; trace1(d->long_label().c_str(), volts); double cb; if (c->cj_adjusted != 0.) { if (volts < m->fc * m->pb) { cb = c->cj_adjusted / pow(1. - (volts / m->pb), m->mj); }else{ cb = (c->cj_adjusted / pow(1. - m->fc, 1. + m->mj)) * (1. - m->fc*(1.+m->mj) + (volts/m->pb)*m->mj); } }else{ cb = 0.; } assert(cb >= 0.); double csw; if (c->cjsw_adjusted != 0.) { if (volts < m->fc * m->pbsw) { csw = c->cjsw_adjusted / pow(1. - (volts / m->pbsw), m->mjsw); }else{ csw = (c->cjsw_adjusted / pow(1. - m->fc, 1. + m->mjsw)) * (1. - m->fc*(1.+m->mjsw) + (volts/m->pbsw)*m->mjsw); } }else{ csw = 0.; } assert(csw >= 0.); double ctt; if (m->tt != 0.) { ctt = p->_gd * m->tt; }else{ ctt = 0.; } assert(ctt >= 0.); trace4("", cb, csw, ctt, cb+csw+ctt); d->_y[0].f1 = cb + csw + ctt; if (d->_sim->analysis_is_tran_dynamic()) { const STORAGE* dd = prechecked_cast(d); assert(dd); double cap = (d->_y[0].f1 + dd->_y[1].f1) / 2; d->_y[0].f0 = (d->_y[0].x - dd->_y[1].x) * cap + dd->_y[1].f0; }else{ assert(d->_sim->analysis_is_static() || d->_sim->analysis_is_restore()); d->_y[0].f0 = d->_y[0].x * d->_y[0].f1; } trace3(d->long_label().c_str(), d->_y[0].x, d->_y[0].f0, d->_y[0].f1); } eval Yj { FPOLY1& y = d->_y[0]; double volts = y.x; double amps = y.f0; trace2(d->long_label().c_str(), volts, amps); int flags = (m->flags & USE_OPT) ? OPT::diodeflags : m->flags; double tempratio = (d->_sim->_temp_c+P_CELSIUS0) / (m->_tnom_c+P_CELSIUS0); double vt = P_K_Q * (d->_sim->_temp_c+P_CELSIUS0) * m->n_factor; region_t oldregion = p->_region; p->_isat = c->is_adjusted * pow(tempratio, m->xti) * exp((m->eg/vt) *(tempratio-1)); trace4("", tempratio, vt, oldregion, p->_isat); if (m->mos_level > 0 || flags & 0040) { // Spice style limiting double vcrit = vt * log(vt / (M_SQRT2 * p->_isat)); double vold = d->_y1.f0; if((volts > vcrit) && (std::abs(volts - vold) > (vt + vt))) { if(vold > 0) { double arg = 1 + (volts - vold) / vt; if(arg > 0) { volts = vold + vt * log(arg); }else{ volts = vcrit; } }else{ volts = vt *log(volts/vt); } }else{ // leave volts as is } } if (m->mos_level > 0) { switch (m->mos_level) { case 1: case 2: case 3: case 6: case 4: case 5: if (volts <= 0.) { p->_region = REVERSE; y.f1 = p->_isat / vt + OPT::gmin; y.f0 = y.f1 * volts; }else{ p->_region = FORWARD; double ev = exp(volts/vt); y.f1 = p->_isat * ev / vt + OPT::gmin; y.f0 = p->_isat * (ev - 1) + OPT::gmin * volts; } break; case 7: case 8: if (volts < .5) { p->_region = REVERSE; double ev = exp(volts/vt); y.f1 = p->_isat * ev / vt + OPT::gmin; y.f0 = p->_isat * (ev - 1) + OPT::gmin * volts; }else{ p->_region = FORWARD; double ev = exp(.5/vt); double t0 = p->_isat * ev / vt; y.f1 = t0 + OPT::gmin; y.f0 = p->_isat * (ev - 1) + t0 * (volts - .5) + OPT::gmin * volts; } break; default: unreachable(); y.f1 = OPT::gmin; y.f0 = volts * y.f1; } }else if (flags & 0040) { // exact Spice model if (volts >= -3*vt) { // forward and weak reversed double evd = exp(volts/vt); y.f0 = p->_isat * (evd-1); y.f1 = p->_isat * evd/vt; }else if (has_good_value(m->bv) || volts >= m->bv) { double arg = 3 * vt / (volts * M_E); // strong reversed arg = arg * arg * arg; y.f0 = -p->_isat * (1+arg); y.f1 = p->_isat * 3 * arg / volts; }else{ incomplete(); double evrev = exp(-(m->bv+volts)/vt); y.f0 = -p->_isat * evrev; y.f1 = p->_isat * evrev / vt; } y.f0 += OPT::gmin * volts; y.f1 += OPT::gmin; }else{ if (c->off && d->_sim->is_initial_step()) { /*initially guess off*/ p->_region = INITOFF; y.f1 = 0.; y.f0 = 0.; if (flags & 0020) { untested(); y.f1 = OPT::gmin; } trace2("initoff", y.f0, y.f1); }else if (volts <= 0. /* && amps < 0.*/) { /* reverse biased */ p->_region = REVERSE; /* x = volts, f(x) = amps */ if (flags & 0010) { untested(); y.f1 = y.f0 = 0.; }else{ double expterm = p->_isat * exp(volts/vt); y.f0 = expterm - p->_isat;/* i = f(x) = _isat * (exp(volts/vt)-1) */ y.f1 = expterm / vt; /* f'(x) = (_isat/vt) * exp(volts/vt) */ } if (flags & 0002) { // g = gmin, maintain actual current y.f1 += OPT::gmin; // 3 is a resistor, R=1/gmin y.f0 += OPT::gmin * volts; } if (flags & 0004) { // 5 is a resistor, R=vt/_isat double x = p->_isat / vt; y.f1 += x; y.f0 += x * volts; } if (flags & 0001) { //y.f0 = y.f1 * volts; // a resistor, R=1/f1 } trace2("reverse", y.f0, y.f1); }else if (volts >= 0. && amps >= 0.) { /* forward biased */ /* x = amps, f(x) = volts */ /* derivation: */ /* if f(x) = log(u): f'(x)=(1/u)(du/dx) */ /* poly1 r; */ /* r.f0 = vt * log(amps/p->_isat +1.); */ /* r.f1 = vt / (_isat + amps); */ /* y.f1 = 1. / r.f1; */ /* y.f0 = amps - r.f0*y.f1 + volts*y.f1; */ p->_region = FORWARD; y.f1 = (p->_isat + amps) / vt; y.f0 = amps - log(amps/p->_isat +1.)*(p->_isat + amps) + volts*y.f1; trace2("forward", y.f0, y.f1); }else{ /* non-converged, inconsistent */ p->_region = UNKNOWN; /* volts and amps have different signs */ y.f1 = p->_isat/vt; /* guess that the voltage should be 0 */ y.f0 = 0.; /* (it usually is very close) */ if (flags & 0001) { /* use the correct value there */ y.f0 = volts * y.f1; } trace2("unknown", y.f0, y.f1); } y.f1 += c->gparallel_adjusted; y.f0 += c->gparallel_adjusted * volts; if (oldregion != p->_region && OPT::dampstrategy & dsDEVLIMIT) { d->_sim->_fulldamp = true; error(bTRACE, p->long_label() + ":device limit damp\n"); } if (flags & 0100) { // twist g to guarantee g >= gmin if (y.f1 < OPT::gmin) { // without changing i y.f1 = OPT::gmin; untested(); }else{ untested(); } } if (flags & 0200) { // add a gmin in parallel y.f1 += OPT::gmin; y.f0 += OPT::gmin * volts; untested(); } if (flags & 0400) { // linearize .. shift I to pass thru 0 untested(); y.f0 = y.f1 * volts; } } trace3(d->long_label().c_str(), y.x, y.f0, y.f1); p->_gd = y.f1; } } /*--------------------------------------------------------------------------*/ model BUILT_IN_DIODE { dev_type BUILT_IN_DIODE; hide_base; inherit CARD; public_keys { d dummy=true; } independent { override { double _tnom_c "" name=TNOM default=OPT::tnom_c; } raw_parameters { double js "= is, saturation current (per area)" name=IS positive default=1e-14; double rs "ohmic resistance (per area)" name=RS positive default=0.0; double n_factor "emission coefficient" name=N positive default=1.0; double tt "transit time" name=TT positive default=0.0; double cjo "cj, zero-bias jct capacitance (per area)" name=CJo positive final_default=0.0; double pb "vj, junction potential" name=PB alt_name=VJ positive final_default=1.0; double mj "m, grading coefficient" name=Mj alt_name=M positive default=0.5; double eg "activation energy" name=EGap alt_name=EG positive default=1.11; double xti "saturation-current temp. exp." name=XTI positive default=3.0; double kf "flicker noise coefficient" name=KF positive default=NA; double af "flicker noise exponent" name=AF positive default=NA; double fc "coef for fwd bias depl cap formula" name=FC positive default=0.5; double bv "reverse breakdown voltage" name=BV positive default=NA; double ibv "current at reverse breakdown" name=IBV positive default=1e-3 print_test="has_good_value(bv)"; /* non-spice extensions */ double cjsw "zero bias sidewall cap (per perim.)" name=CJSw alt_name=CJS positive default=0.0 print_test="cjsw != 0."; double pbsw "sidewall junction potential" name=PBSw alt_name=PBS positive final_default=pb print_test="cjsw != 0."; double mjsw "sidewall grading coefficient" name=MJSw alt_name=MJS positive final_default=0.33 print_test="cjsw != 0."; double gparallel "parallel conductance" name=GParallel alt_name=GP default=0.0 print_test="gparallel != 0."; int flags "" name=FLAGS default="int(USE_OPT)" print_test="!(flags & USE_OPT)"; int mos_level "" default=0 print_test="mos_level.has_hard_value()"; } code_post { if (bv == 0.) { bv = NA; } } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_dot.h�����������������������������������������������������������������������������������������0000664�0000000�0000000�00000003424�11454012162�0013106�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_dot.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2007 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ #ifndef D_DOT_H #define D_DOT_H #include "e_card.h" /*--------------------------------------------------------------------------*/ class DEV_DOT : public CARD { private: std::string _s; explicit DEV_DOT(const DEV_DOT& p) :CARD(p) {set_constant(true);} public: explicit DEV_DOT() :CARD() {set_constant(true);} private: // override virtual std::string value_name()const {return "";} char id_letter()const {untested();return '\0';} std::string dev_type()const {untested();return "dotcard";} CARD* clone()const {return new DEV_DOT(*this);} public: void set(const std::string& S) {_s = S;} const std::string& s()const {return _s;} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_logic.cc��������������������������������������������������������������������������������������0000664�0000000�0000000�00000037510�11454012162�0013556�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_logic.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * logic model and device. * netlist syntax: * device: mxxxx out gnd vdd in1 in2 ... family gatetype * model: .model mname LOGIC */ //testing=script,sparse 2006.07.17 #include "d_subckt.h" #include "u_xprobe.h" #include "d_logic.h" /*--------------------------------------------------------------------------*/ int DEV_LOGIC::_count = -1; int COMMON_LOGIC::_count = -1; int MODEL_LOGIC::_count = -1; // there is one in e_node.cc, and the dispatcher static LOGIC_NONE Default_LOGIC(CC_STATIC); /*--------------------------------------------------------------------------*/ static DEV_LOGIC p1; static DISPATCHER::INSTALL d1(&device_dispatcher, "U|logic", &p1); /*--------------------------------------------------------------------------*/ static MODEL_LOGIC p2(&p1); static DISPATCHER::INSTALL d2(&model_dispatcher, "logic", &p2); /*--------------------------------------------------------------------------*/ DEV_LOGIC::DEV_LOGIC() :ELEMENT(), _lastchangenode(0), _quality(qGOOD), _failuremode("ok"), _oldgatemode(moUNKNOWN), _gatemode(moUNKNOWN) { attach_common(&Default_LOGIC); _n = nodes; ++_count; } /*--------------------------------------------------------------------------*/ DEV_LOGIC::DEV_LOGIC(const DEV_LOGIC& p) :ELEMENT(p), _lastchangenode(0), _quality(qGOOD), _failuremode("ok"), _oldgatemode(moUNKNOWN), _gatemode(moUNKNOWN) { assert(max_nodes() == PORTS_PER_GATE); for (int ii = 0; ii < max_nodes(); ++ii) { nodes[ii] = p.nodes[ii]; } _n = nodes; ++_count; } /*--------------------------------------------------------------------------*/ void DEV_LOGIC::expand() { ELEMENT::expand(); const COMMON_LOGIC* c = prechecked_cast(common()); assert(c); attach_model(); const MODEL_LOGIC* m = dynamic_cast(c->model()); if (!m) { throw Exception_Model_Type_Mismatch(long_label(), c->modelname(), "logic family (LOGIC)"); }else{ } std::string subckt_name(c->modelname()+c->name()+to_string(c->incount)); try { const CARD* model = find_looking_out(subckt_name); if(!dynamic_cast(model)) {untested(); error(((!_sim->is_first_expand()) ? (bDEBUG) : (bWARNING)), long_label() + ": " + subckt_name + " is not a subckt, forcing digital\n"); }else{ _gatemode = OPT::mode; renew_subckt(model, this, scope(), NULL/*&(c->_params)*/); subckt()->expand(); } }catch (Exception_Cant_Find&) { error(((!_sim->is_first_expand()) ? (bDEBUG) : (bWARNING)), long_label() + ": can't find subckt: " + subckt_name + ", forcing digital\n"); } assert(!is_constant()); /* is a BUG */ } /*--------------------------------------------------------------------------*/ void DEV_LOGIC::tr_iwant_matrix() { if (subckt()) { subckt()->tr_iwant_matrix(); }else{ } tr_iwant_matrix_passive(); } /*--------------------------------------------------------------------------*/ void DEV_LOGIC::tr_begin() { ELEMENT::tr_begin(); if (!subckt()) { _gatemode = moDIGITAL; _n[OUTNODE]->set_mode(_gatemode); _oldgatemode = _gatemode; }else{ _gatemode = (OPT::mode==moMIXED) ? moANALOG : OPT::mode; _n[OUTNODE]->set_mode(_gatemode); _oldgatemode = _gatemode; subckt()->tr_begin(); } } /*--------------------------------------------------------------------------*/ void DEV_LOGIC::tr_restore() {untested(); ELEMENT::tr_restore(); if (!subckt()) {untested(); _gatemode = moDIGITAL; }else{untested(); _gatemode = (OPT::mode==moMIXED) ? moANALOG : OPT::mode; subckt()->tr_restore(); } } /*--------------------------------------------------------------------------*/ void DEV_LOGIC::dc_advance() { ELEMENT::dc_advance(); if (_gatemode != _oldgatemode) {untested(); tr_unload(); _n[OUTNODE]->set_mode(_gatemode); _oldgatemode = _gatemode; }else{ } switch (_gatemode) { case moUNKNOWN: unreachable(); break; case moMIXED: unreachable(); break; case moANALOG: assert(subckt()); subckt()->dc_advance(); break; case moDIGITAL: if (_n[OUTNODE]->in_transit()) { //q_eval(); evalq is not used for DC _n[OUTNODE]->propagate(); }else{ } break; } } /*--------------------------------------------------------------------------*/ /* tr_advance: the first to run on a new time step. * It sets up preconditions for the new time. */ void DEV_LOGIC::tr_advance() { ELEMENT::tr_advance(); if (_gatemode != _oldgatemode) { tr_unload(); _n[OUTNODE]->set_mode(_gatemode); _oldgatemode = _gatemode; }else{ } switch (_gatemode) { case moUNKNOWN: unreachable(); break; case moMIXED: unreachable(); break; case moANALOG: assert(subckt()); subckt()->tr_advance(); break; case moDIGITAL: if (_n[OUTNODE]->in_transit()) { q_eval(); if (_sim->_time0 >= _n[OUTNODE]->final_time()) { _n[OUTNODE]->propagate(); }else{untested(); } }else{ } break; } } void DEV_LOGIC::tr_regress() {itested(); ELEMENT::tr_regress(); if (_gatemode != _oldgatemode) {itested(); tr_unload(); _n[OUTNODE]->set_mode(_gatemode); _oldgatemode = _gatemode; }else{itested(); } switch (_gatemode) { case moUNKNOWN: unreachable(); break; case moMIXED: unreachable(); break; case moANALOG: itested(); assert(subckt()); subckt()->tr_regress(); break; case moDIGITAL: itested(); if (_n[OUTNODE]->in_transit()) {itested(); q_eval(); if (_sim->_time0 >= _n[OUTNODE]->final_time()) {itested(); _n[OUTNODE]->propagate(); }else{itested(); } }else{itested(); } break; } } /*--------------------------------------------------------------------------*/ /* tr_needs_eval * in digital mode ... DC always returns true, to queue it. * tran always returns false, already queued by tr_advance if needed */ bool DEV_LOGIC::tr_needs_eval()const { switch (_gatemode) { case moUNKNOWN: unreachable(); break; case moMIXED: unreachable(); break; case moDIGITAL: //assert(!is_q_for_eval()); if (_sim->analysis_is_restore()) {untested(); }else if (_sim->analysis_is_static()) { }else{ } return (_sim->analysis_is_static() || _sim->analysis_is_restore()); case moANALOG: untested(); assert(!is_q_for_eval()); assert(subckt()); return subckt()->tr_needs_eval(); } unreachable(); return false; } /*--------------------------------------------------------------------------*/ void DEV_LOGIC::tr_queue_eval() { switch (_gatemode) { case moUNKNOWN: unreachable(); break; case moMIXED: unreachable(); break; case moDIGITAL: ELEMENT::tr_queue_eval(); break; case moANALOG: assert(subckt()); subckt()->tr_queue_eval(); break; } } /*--------------------------------------------------------------------------*/ bool DEV_LOGIC::tr_eval_digital() { assert(_gatemode == moDIGITAL); if (_sim->analysis_is_restore()) {untested(); }else if (_sim->analysis_is_static()) { }else{ } if (_sim->analysis_is_static() || _sim->analysis_is_restore()) { tr_accept(); }else{ assert(_sim->analysis_is_tran_dynamic()); } const COMMON_LOGIC* c = prechecked_cast(common()); assert(c); const MODEL_LOGIC* m = prechecked_cast(c->model()); assert(m); _y[0].x = 0.; _y[0].f1 = _n[OUTNODE]->to_analog(m); _y[0].f0 = 0.; _m0.x = 0.; _m0.c1 = 1./m->rs; _m0.c0 = _y[0].f1 / -m->rs; set_converged(conv_check()); store_values(); q_load(); return converged(); } /*--------------------------------------------------------------------------*/ bool DEV_LOGIC::do_tr() { switch (_gatemode) { case moUNKNOWN: unreachable(); break; case moMIXED: unreachable(); break; case moDIGITAL: set_converged(tr_eval_digital()); break; case moANALOG: assert(subckt()); set_converged(subckt()->do_tr()); break; } return converged(); } /*--------------------------------------------------------------------------*/ void DEV_LOGIC::tr_load() { switch (_gatemode) { case moUNKNOWN: unreachable(); break; case moMIXED: unreachable(); break; case moDIGITAL: tr_load_passive(); break; case moANALOG: assert(subckt()); subckt()->tr_load(); break; } } /*--------------------------------------------------------------------------*/ TIME_PAIR DEV_LOGIC::tr_review() { // not calling ELEMENT::tr_review(); q_accept(); //digital mode queues events explicitly in tr_accept switch (_gatemode) { case moUNKNOWN: unreachable(); break; case moMIXED: unreachable(); break; case moDIGITAL: _time_by.reset(); break; case moANALOG: assert(subckt()); _time_by = subckt()->tr_review(); break; } return _time_by; } /*--------------------------------------------------------------------------*/ /* tr_accept: This runs after everything has passed "review". * It sets up and queues transitions, and sometimes determines logic states. */ void DEV_LOGIC::tr_accept() { assert(_gatemode == moDIGITAL || _gatemode == moANALOG); const COMMON_LOGIC* c = prechecked_cast(common()); assert(c); const MODEL_LOGIC* m = prechecked_cast(c->model()); assert(m); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Check quality and get node info to local array. */ /* side effect --- generate digital values for analog nodes */ assert(PORTS_PER_GATE == max_nodes()); { _n[OUTNODE]->to_logic(m); _quality = _n[OUTNODE]->quality(); /* the worst quality on this device */ _failuremode = _n[OUTNODE]->failure_mode(); /* what is wrong with it? */ _lastchangenode = OUTNODE; /* which node changed most recently */ int lastchangeiter=_n[OUTNODE]->d_iter();/* iteration # when it changed */ trace0(long_label().c_str()); trace2(_n[OUTNODE]->failure_mode().c_str(), OUTNODE, _n[OUTNODE]->quality()); for (int ii = BEGIN_IN; ii < net_nodes(); ++ii) { _n[ii]->to_logic(m); if (_n[ii]->quality() < _quality) { _quality = _n[ii]->quality(); _failuremode = _n[ii]->failure_mode(); }else{ } if (_n[ii]->d_iter() >= lastchangeiter) { lastchangeiter = _n[ii]->d_iter(); _lastchangenode = ii; }else{ } trace2(_n[ii]->failure_mode().c_str(), ii, _n[ii]->quality()); } /* If _lastchangenode == OUTNODE, no new changes, bypass may be ok. * Otherwise, an input changed. Need to evaluate. * If all quality are good, can evaluate as digital. * Otherwise need to evaluate as analog. */ trace3(_failuremode.c_str(), _lastchangenode, lastchangeiter, _quality); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (want_analog()) { if (_gatemode == moDIGITAL) {untested(); error(bTRACE, "%s:%u:%g switch to analog, %s\n", long_label().c_str(), _sim->iteration_tag(), _sim->_time0, _failuremode.c_str()); _oldgatemode = _gatemode; _gatemode = moANALOG; }else{ } assert(_gatemode == moANALOG); }else{ assert(want_digital()); if (_gatemode == moANALOG) { error(bTRACE, "%s:%u:%g switch to digital\n", long_label().c_str(), _sim->iteration_tag(), _sim->_time0); _oldgatemode = _gatemode; _gatemode = moDIGITAL; }else{ } assert(_gatemode == moDIGITAL); if (_sim->analysis_is_restore()) {untested(); }else if (_sim->analysis_is_static()) { }else{ } if (!_sim->_bypass_ok || _lastchangenode != OUTNODE || _sim->analysis_is_static() || _sim->analysis_is_restore()) { LOGICVAL future_state = c->logic_eval(&_n[BEGIN_IN]); // ^^^^^^^^^^ if ((_n[OUTNODE]->is_unknown()) && (_sim->analysis_is_static() || _sim->analysis_is_restore())) { _n[OUTNODE]->force_initial_value(future_state); /* This happens when initial DC is digital. * Answers could be wrong if order in netlist is reversed */ }else if (future_state != _n[OUTNODE]->lv()) { assert(future_state != lvUNKNOWN); switch (future_state) { case lvSTABLE0: /*nothing*/ break; case lvRISING: future_state=lvSTABLE0; break; case lvFALLING: future_state=lvSTABLE1; break; case lvSTABLE1: /*nothing*/ break; case lvUNKNOWN: unreachable(); break; } /* This handling of rising and falling may seem backwards. * These states occur when the value has been contaminated * by another pending action. The "old" value is the * value without this contamination. * This code is planned for replacement as part of VHDL/Verilog * conversion, so the kluge stays in for now. */ assert(future_state.lv_old() == future_state.lv_future()); if (_n[OUTNODE]->lv() == lvUNKNOWN || future_state.lv_future() != _n[OUTNODE]->lv_future()) { _n[OUTNODE]->set_event(m->delay, future_state); _sim->new_event(_n[OUTNODE]->final_time()); //assert(future_state == _n[OUTNODE].lv_future()); if (_lastchangenode == OUTNODE) { unreachable(); error(bDANGER, "%s:%u:%g non-event state change\n", long_label().c_str(), _sim->iteration_tag(), _sim->_time0); }else{ } }else{ } }else{ } }else{ } } } /*--------------------------------------------------------------------------*/ void DEV_LOGIC::tr_unload() { if (subckt()) { subckt()->tr_unload(); }else{untested(); } tr_unload_passive(); } /*--------------------------------------------------------------------------*/ void DEV_LOGIC::ac_iwant_matrix() { if (subckt()) { subckt()->ac_iwant_matrix(); }else{ } } /*--------------------------------------------------------------------------*/ void DEV_LOGIC::ac_begin() {untested(); if (subckt()) {untested(); subckt()->ac_begin(); }else{untested(); error(bWARNING, long_label() + ": no logic in AC analysis\n"); } } /*--------------------------------------------------------------------------*/ double DEV_LOGIC::tr_probe_num(const std::string& what)const { return _n[OUTNODE]->tr_probe_num(what); } /*--------------------------------------------------------------------------*/ XPROBE DEV_LOGIC::ac_probe_ext(const std::string& what)const {untested(); return _n[OUTNODE]->ac_probe_ext(what); } /*--------------------------------------------------------------------------*/ bool DEV_LOGIC::want_analog()const { return subckt() && ((OPT::mode == moANALOG) || (OPT::mode == moMIXED && _quality != qGOOD)); } /*--------------------------------------------------------------------------*/ bool DEV_LOGIC::want_digital()const { return !subckt() || ((OPT::mode == moDIGITAL) || (OPT::mode == moMIXED && _quality == qGOOD)); } /*--------------------------------------------------------------------------*/ bool COMMON_LOGIC::operator==(const COMMON_COMPONENT& x)const { const COMMON_LOGIC* p = dynamic_cast(&x); bool rv = p && incount == p->incount && COMMON_COMPONENT::operator==(x); if (rv) { }else{ } return rv; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_logic.h���������������������������������������������������������������������������������������0000664�0000000�0000000�00000025261�11454012162�0013420�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_logic.h,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * data structures and defaults for logic model. */ //testing=script,sparse 2006.07.17 #ifndef D_LOGIC_H #define D_LOGIC_H #include "e_model.h" #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ enum {PORTS_PER_GATE = 10}; /*--------------------------------------------------------------------------*/ class DEV_LOGIC : public ELEMENT { public: enum {OUTNODE=0,GND_NODE=1,PWR_NODE=2,ENABLE=3,BEGIN_IN=4}; //node labels private: int _lastchangenode; int _quality; std::string _failuremode; smode_t _oldgatemode; smode_t _gatemode; static int _count; node_t nodes[PORTS_PER_GATE]; /* PORTS_PER_GATE <= PORTSPERSUBCKT */ public: explicit DEV_LOGIC(); explicit DEV_LOGIC(const DEV_LOGIC& p); ~DEV_LOGIC() {--_count;} private: // override virtuals char id_letter()const {return 'U';} std::string value_name()const {return "#";} bool print_type_in_spice()const {return true;} std::string dev_type()const {assert(has_common()); return (common()->modelname() + " " + common()->name()).c_str();} int tail_size()const {return 2;} int max_nodes()const {return PORTS_PER_GATE;} int min_nodes()const {return BEGIN_IN+1;} int matrix_nodes()const {return 2;} int net_nodes()const {return _net_nodes;} CARD* clone()const {return new DEV_LOGIC(*this);} void precalc_first() {ELEMENT::precalc_first(); if (subckt()) {subckt()->precalc_first();}} void expand(); void precalc_last() {ELEMENT::precalc_last(); if (subckt()) {subckt()->precalc_last();}} //void map_nodes(); void tr_iwant_matrix(); void tr_begin(); void tr_restore(); void dc_advance(); void tr_advance(); void tr_regress(); bool tr_needs_eval()const; void tr_queue_eval(); bool do_tr(); void tr_load(); TIME_PAIR tr_review(); void tr_accept(); void tr_unload(); double tr_involts()const {unreachable(); return 0;} //double tr_input()const //ELEMENT double tr_involts_limited()const {unreachable(); return 0;} //double tr_input_limited()const //ELEMENT //double tr_amps()const //ELEMENT double tr_probe_num(const std::string&)const; void ac_iwant_matrix(); void ac_begin(); void do_ac() {untested(); assert(subckt()); subckt()->do_ac();} void ac_load() {untested(); assert(subckt()); subckt()->ac_load();} COMPLEX ac_involts()const {unreachable(); return 0.;} COMPLEX ac_amps()const {unreachable(); return 0.;} XPROBE ac_probe_ext(const std::string&)const; std::string port_name(int)const {untested(); incomplete(); return ""; } public: static int count() {return _count;} private: bool tr_eval_digital(); bool want_analog()const; bool want_digital()const; }; /*--------------------------------------------------------------------------*/ class MODEL_LOGIC : public MODEL_CARD { private: explicit MODEL_LOGIC(const MODEL_LOGIC& p); public: explicit MODEL_LOGIC(const DEV_LOGIC*); ~MODEL_LOGIC() {--_count;} private: // override virtuals std::string dev_type()const {return "logic";} CARD* clone()const {return new MODEL_LOGIC(*this);} void precalc_first(); void set_param_by_index(int, std::string&, int); bool param_is_printable(int)const; std::string param_name(int)const; std::string param_name(int,int)const; std::string param_value(int)const; int param_count()const {return (13 + MODEL_CARD::param_count());} public: static int count() {return _count;} public: /* ----- digital mode ----- */ PARAMETER delay; /* propagation delay */ /* -- conversion parameters both ways -- */ PARAMETER vmax; /* nominal volts for logic 1 */ PARAMETER vmin; /* nominal volts for logic 0 */ PARAMETER unknown; /* nominal volts for unknown (bogus) */ /* ---- D to A conversion ---- */ PARAMETER rise; /* rise time (time in slope) */ PARAMETER fall; /* fall time (time in slope) */ PARAMETER rs; /* series resistance -- strong */ PARAMETER rw; /* series resistance -- weak */ /* ---- A to D conversion ---- */ PARAMETER th1; /* threshold for 1 as fraction of range */ PARAMETER th0; /* threshold for 0 as fraction of range */ /* ---- quality judgement parameters ---- */ PARAMETER mr; /* margin rise - how much worse rise can be */ PARAMETER mf; /* margin fall - how much worse fall can be */ PARAMETER over; /* overshoot limit - as fraction of range */ public: // calculated parameters double range; /* vmax - vmin */ private: static int _count; }; /*--------------------------------------------------------------------------*/ class INTERFACE COMMON_LOGIC : public COMMON_COMPONENT { protected: explicit COMMON_LOGIC(int c=0) :COMMON_COMPONENT(c), incount(0) {++_count;} explicit COMMON_LOGIC(const COMMON_LOGIC& p) :COMMON_COMPONENT(p), incount(p.incount) {++_count;} public: ~COMMON_LOGIC() {--_count;} bool operator==(const COMMON_COMPONENT&)const; static int count() {return _count;} virtual LOGICVAL logic_eval(const node_t*)const = 0; public: int incount; protected: static int _count; }; /*--------------------------------------------------------------------------*/ class LOGIC_AND : public COMMON_LOGIC { private: explicit LOGIC_AND(const LOGIC_AND& p) :COMMON_LOGIC(p){untested();++_count;} COMMON_COMPONENT* clone()const {untested(); return new LOGIC_AND(*this);} public: explicit LOGIC_AND(int c=0) :COMMON_LOGIC(c) {untested();} LOGICVAL logic_eval(const node_t* n)const {untested(); LOGICVAL out(n[0]->lv()); for (int ii=1; iilv(); } return out; } virtual std::string name()const {itested();return "and";} }; /*--------------------------------------------------------------------------*/ class LOGIC_NAND : public COMMON_LOGIC { private: explicit LOGIC_NAND(const LOGIC_NAND&p):COMMON_LOGIC(p){++_count;} COMMON_COMPONENT* clone()const {return new LOGIC_NAND(*this);} public: explicit LOGIC_NAND(int c=0) :COMMON_LOGIC(c) {} LOGICVAL logic_eval(const node_t* n)const {untested(); LOGICVAL out(n[0]->lv()); for (int ii=1; iilv(); } return ~out; } virtual std::string name()const {itested();return "nand";} }; /*--------------------------------------------------------------------------*/ class LOGIC_OR : public COMMON_LOGIC { private: explicit LOGIC_OR(const LOGIC_OR& p) :COMMON_LOGIC(p){untested();++_count;} COMMON_COMPONENT* clone()const {untested(); return new LOGIC_OR(*this);} public: explicit LOGIC_OR(int c=0) :COMMON_LOGIC(c) {untested();} LOGICVAL logic_eval(const node_t* n)const {untested(); LOGICVAL out(n[0]->lv()); for (int ii=1; iilv(); } return out; } virtual std::string name()const {itested();return "or";} }; /*--------------------------------------------------------------------------*/ class LOGIC_NOR : public COMMON_LOGIC { private: explicit LOGIC_NOR(const LOGIC_NOR& p) :COMMON_LOGIC(p) {++_count;} COMMON_COMPONENT* clone()const {return new LOGIC_NOR(*this);} public: explicit LOGIC_NOR(int c=0) :COMMON_LOGIC(c) {} LOGICVAL logic_eval(const node_t* n)const { LOGICVAL out(n[0]->lv()); for (int ii=1; iilv(); } return ~out; } virtual std::string name()const {return "nor";} }; /*--------------------------------------------------------------------------*/ class LOGIC_XOR : public COMMON_LOGIC { private: explicit LOGIC_XOR(const LOGIC_XOR& p) :COMMON_LOGIC(p){untested();++_count;} COMMON_COMPONENT* clone()const {untested(); return new LOGIC_XOR(*this);} public: explicit LOGIC_XOR(int c=0) :COMMON_LOGIC(c) {untested();} LOGICVAL logic_eval(const node_t* n)const {untested(); LOGICVAL out(n[0]->lv()); for (int ii=1; iilv(); } return out; } virtual std::string name()const {itested();return "xor";} }; /*--------------------------------------------------------------------------*/ class LOGIC_XNOR : public COMMON_LOGIC { private: explicit LOGIC_XNOR(const LOGIC_XNOR&p):COMMON_LOGIC(p){untested();++_count;} COMMON_COMPONENT* clone()const {untested(); return new LOGIC_XNOR(*this);} public: explicit LOGIC_XNOR(int c=0) :COMMON_LOGIC(c) {untested();} LOGICVAL logic_eval(const node_t* n)const {untested(); LOGICVAL out(n[0]->lv()); for (int ii=1; iilv(); } return ~out; } virtual std::string name()const {itested();return "xnor";} }; /*--------------------------------------------------------------------------*/ class LOGIC_INV : public COMMON_LOGIC { private: explicit LOGIC_INV(const LOGIC_INV& p) :COMMON_LOGIC(p){++_count;} COMMON_COMPONENT* clone()const {return new LOGIC_INV(*this);} public: explicit LOGIC_INV(int c=0) :COMMON_LOGIC(c) {} LOGICVAL logic_eval(const node_t* n)const { return ~n[0]->lv(); } virtual std::string name()const {return "inv";} }; /*--------------------------------------------------------------------------*/ class LOGIC_NONE : public COMMON_LOGIC { private: explicit LOGIC_NONE(const LOGIC_NONE&p):COMMON_LOGIC(p){itested();++_count;} COMMON_COMPONENT* clone()const {itested(); return new LOGIC_NONE(*this);} public: explicit LOGIC_NONE(int c=0) :COMMON_LOGIC(c) {} LOGICVAL logic_eval(const node_t*)const {untested(); return lvUNKNOWN; } virtual std::string name()const {untested();return "error";} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_logicmod.cc�����������������������������������������������������������������������������������0000664�0000000�0000000�00000012427�11454012162�0014256�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_logicmod.cc,v 26.127 2009/11/09 16:06:11 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * logic model and device. * netlist syntax: * device: mxxxx vdd out in1 in2 ... family gatetype * model: .model mname LOGIC */ //testing=script 2006.07.17 #include "d_logic.h" /*--------------------------------------------------------------------------*/ MODEL_LOGIC::MODEL_LOGIC(const DEV_LOGIC* p) :MODEL_CARD(p), delay (1e-9), vmax (5.), vmin (0.), unknown((vmax+vmin)/2), rise (delay / 2), fall (delay / 2), rs (100.), rw (1e9), th1 (.75), th0 (.25), mr (5.), mf (5.), over (.1), range (vmax - vmin) { ++_count; } /*--------------------------------------------------------------------------*/ MODEL_LOGIC::MODEL_LOGIC(const MODEL_LOGIC& p) :MODEL_CARD(p), delay (p.delay), vmax (p.vmax), vmin (p.vmin), unknown(p.unknown), rise (p.rise), fall (p.fall), rs (p.rs), rw (p.rw), th1 (p.th1), th0 (p.th0), mr (p.mr), mf (p.mf), over (p.over), range (p.range) { ++_count; } /*--------------------------------------------------------------------------*/ void MODEL_LOGIC::precalc_first() { MODEL_CARD::precalc_first(); const CARD_LIST* par_scope = scope(); assert(par_scope); delay.e_val(1e-9, par_scope); vmax.e_val(5., par_scope); vmin.e_val(0., par_scope); unknown.e_val((vmax+vmin)/2, par_scope); rise.e_val(delay / 2, par_scope); fall.e_val(delay / 2, par_scope); rs.e_val(100., par_scope); rw.e_val(1e9, par_scope); th1.e_val(.75, par_scope); th0.e_val(.25, par_scope); mr.e_val(5., par_scope); mf.e_val(5., par_scope); over.e_val(.1, par_scope); range = vmax - vmin; } /*--------------------------------------------------------------------------*/ void MODEL_LOGIC::set_param_by_index(int i, std::string& value, int offset) { switch (MODEL_LOGIC::param_count() - 1 - i) { case 0: delay = value; break; case 1: vmax = value; break; case 2: vmin = value; break; case 3: unknown = value; break; case 4: rise = value; break; case 5: fall = value; break; case 6: rs = value; break; case 7: rw = value; break; case 8: th1 = value; break; case 9: th0 = value; break; case 10: mr = value; break; case 11: mf = value; break; case 12: over = value; break; default: MODEL_CARD::set_param_by_index(i, value, offset); break; } } /*--------------------------------------------------------------------------*/ bool MODEL_LOGIC::param_is_printable(int i)const { switch (MODEL_LOGIC::param_count() - 1 - i) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: return true; default: return MODEL_CARD::param_is_printable(i); } } /*--------------------------------------------------------------------------*/ std::string MODEL_LOGIC::param_name(int i)const { switch (MODEL_LOGIC::param_count() - 1 - i) { case 0: return "delay"; case 1: return "vmax"; case 2: return "vmin"; case 3: return "unknown"; case 4: return "rise"; case 5: return "fall"; case 6: return "rs"; case 7: return "rw"; case 8: return "thh"; case 9: return "thl"; case 10: return "mr"; case 11: return "mf"; case 12: return "over"; default: return MODEL_CARD::param_name(i); } } /*--------------------------------------------------------------------------*/ std::string MODEL_LOGIC::param_name(int i, int j)const { if (j == 0) { return param_name(i); }else if (i >= MODEL_CARD::param_count()) { return ""; }else{ return MODEL_CARD::param_name(i, j); } } /*--------------------------------------------------------------------------*/ std::string MODEL_LOGIC::param_value(int i)const { switch (MODEL_LOGIC::param_count() - 1 - i) { case 0: return delay.string(); case 1: return vmax.string(); case 2: return vmin.string(); case 3: return unknown.string(); case 4: return rise.string(); case 5: return fall.string(); case 6: return rs.string(); case 7: return rw.string(); case 8: return th1.string(); case 9: return th0.string(); case 10: return mr.string(); case 11: return mf.string(); case 12: return over.string(); default: return MODEL_CARD::param_value(i); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_mos.model�������������������������������������������������������������������������������������0000664�0000000�0000000�00000046700�11454012162�0013773�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: d_mos.model,v 26.132 2009/11/24 04:26:37 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * data structures and defaults for mos model. * internal units all mks (meters) * but some user input parameters are in cm. * * netlist syntax: * device: mxxxx d g s b mname * model: .model mname NMOS * or .model mname PMOS */ h_headers { #include "d_diode.h" } cc_headers { #include "u_limit.h" #include "e_storag.h" #include "d_mos_base.h" } /*--------------------------------------------------------------------------*/ device BUILT_IN_MOS { parse_name mosfet; model_type BUILT_IN_MOS_BASE; id_letter M; circuit { sync; ports {d g s b}; local_nodes { id short_to=d short_if="!OPT::rstray || s->rd == 0."; is short_to=s short_if="!OPT::rstray || s->rs == 0."; } args db BUILT_IN_DIODE { area = double(s->ad); perim = double(c->pd); is_raw = double(s->idsat); cj_raw = double(m->cbd); cjsw_raw = NA; off = true; set_modelname(modelname()); attach(model()); } args sb BUILT_IN_DIODE { area = double(s->as); perim = double(c->ps); is_raw = double(s->issat); cj_raw = double(m->cbs); cjsw_raw = NA; off = true; set_modelname(modelname()); attach(model()); } resistor Rs {s is} value="s->rs" omit="!OPT::rstray || s->rs == 0."; resistor Rd {d id} value="s->rd" omit="!OPT::rstray || s->rd == 0."; diode Ddb {b id} args="db" reverse="m->polarity==pP" omit="_n[n_b].n_() == _n[n_d].n_() || s->idsat == 0."; diode Dsb {b is} args="sb" reverse="m->polarity==pP" omit="_n[n_b].n_() == _n[n_s].n_() || s->issat == 0."; capacitor Cgs {g is} value="s->cgso" eval=Cgs omit="!OPT::cstray || _n[n_g].n_() == _n[n_s].n_()"; capacitor Cgd {g id} value="s->cgdo" eval=Cgd omit="!OPT::cstray || _n[n_g].n_() == _n[n_d].n_()"; capacitor Cgb {g b} value="s->cgbo" eval=Cgb omit="!OPT::cstray || _n[n_b].n_() == _n[n_g].n_()"; /* fpoly_cap Cqgs {g is g b is b id b} state=qgs // qgate, cgs, cggb, cgsb, cgdb omit="m->cmodel != 0 || !OPT::cstray || _n[n_g].n_() == _n[n_is].n_()"; fpoly_cap Cqgd {g id g b id b is b} state=qgd // qgate, cgs, cggb, cgsb, cgdb omit="m->cmodel != 0 || !OPT::cstray || _n[n_g].n_() == _n[n_id].n_()"; fpoly_cap Cqds {id is g b is b id b} state=qdrn // qdrn, cds, cdgb, cdsb, cddb omit="m->cmodel != 0 || !OPT::cstray || _n[n_id].n_() == _n[n_is].n_()"; fpoly_cap Cqbs {b is g b is b id b} state=qbs omit="m->cmodel != 0 || !OPT::cstray || _n[n_b].n_() == _n[n_is].n_()"; fpoly_cap Cqbd {b id g b id b is b} state=qbd omit="m->cmodel != 0 || !OPT::cstray || _n[n_b].n_() == _n[n_id].n_()"; */ cpoly_g Ids {id is g is id g b is id b} state=idsxxx; cpoly_g Idb {id b id is g is b is} state=idbxxx omit="!(m->needs_isub) || _n[n_d].n_() == _n[n_b].n_()"; cpoly_g Isb {is b is id g id b id} state=isbxxx omit="!(m->needs_isub) || _n[n_s].n_() == _n[n_b].n_()"; } tr_probe { v = "@n_d[V] - @n_s[V]"; vds = "@n_d[V] - @n_s[V]"; vgs = "@n_g[V] - @n_s[V]"; vbs = "@n_b[V] - @n_s[V]"; "vdsi{nt}" = "vds"; "vgsi{nt}" = "vgs"; "vbsi{nt}" = "vbs"; vgd = "@n_g[V] - @n_d[V]"; vbd = "@n_b[V] - @n_d[V]"; vsd = "@n_s[V] - @n_d[V]"; vdm = "(@n_d[V] - @n_s[V] + @n_d[V] - @n_d[V]) / 2."; vgm = "(@n_g[V] - @n_s[V] + @n_g[V] - @n_d[V]) / 2."; vbm = "(@n_b[V] - @n_s[V] + @n_b[V] - @n_d[V]) / 2."; vsm = "(@n_s[V] - @n_s[V] + @n_s[V] - @n_d[V]) / 2."; vdg = "@n_d[V] - @n_g[V]"; vbg = "@n_b[V] - @n_g[V]"; vsg = "@n_s[V] - @n_g[V]"; vdb = "@n_d[V] - @n_b[V]"; vgb = "@n_g[V] - @n_b[V]"; vsb = "@n_s[V] - @n_b[V]"; vd = "@n_d[V]"; vg = "@n_g[V]"; vb = "@n_b[V]"; vs = "@n_s[V]"; "i{d}" = "(_Rd) ? @Rd[I] : (@Ids[I] - @Cgd[I] - @Ddb[I] * m->polarity)"; is = "(_Rs) ? @Rs[I] : (-@Ids[I] - @Cgs[I] - @Dsb[I] * m->polarity)"; ig = "@Cgs[I] + @Cgd[I] + @Cgb[I]"; ib = "- @Ddb[I] * m->polarity - @Dsb[I] * m->polarity - @Cgb[I]"; ibd = "@Ddb[I]"; ibs = "@Dsb[I]"; "cgso{vl}" = "@Cgs[NV]"; "cgdo{vl}" = "@Cgd[NV]"; "cgbo{vl}" = "@Cgb[NV]"; cgst = "@Cgs[EV]"; cgdt = "@Cgd[EV]"; cgbt = "@Cgb[EV]"; "cgs{m}" = "@Cgs[EV] - @Cgs[NV]"; "cgd{m}" = "@Cgd[EV] - @Cgd[NV]"; "cgb{m}" = "@Cgb[EV] - @Cgb[NV]"; cbd = "@Ddb[Cap]"; cbs = "@Dsb[Cap]"; cgate = "s->cgate"; gm = "(reversed) ? gmr : gmf"; "gmb{s}" = "(reversed) ? gmbr : gmbf"; gbd = "@Ddb[G]"; gbs = "@Dsb[G]"; vth = "von * m->polarity"; ids = "m->polarity * ((reversed) ? -ids : ids)"; "idst{ray}" = "- @Cgd[I] + @Ddb[I] * m->polarity"; p ="@Rs[P] +@Rd[P] +@Ddb[P] +@Dsb[P] +@Cgs[P] +@Cgd[P] +@Cgb[P] +@Ids[P]"; pd="@Rs[PD]+@Rd[PD]+@Ddb[PD]+@Dsb[PD]+@Cgs[PD]+@Cgd[PD]+@Cgb[PD]+@Ids[PD]"; ps="@Rs[PS]+@Rd[PS]+@Ddb[PS]+@Dsb[PS]+@Cgs[PS]+@Cgd[PS]+@Cgb[PS]+@Ids[PS]"; REgion = "static_cast((!cutoff) + (!subthreshold * 2) + (saturated * 4) + (sbfwd * 10) + ((vbs > vds) * 20) + (punchthru * 40)) * ((reversed)? -1 : 1)"; SUBthreshold = "static_cast(subthreshold)"; CUToff = "static_cast(cutoff)"; SATurated= "static_cast(saturated)"; TRIode = "static_cast(!saturated && !subthreshold)"; SBFwd = "static_cast(sbfwd)"; DBFwd = "static_cast(vbs > vds)"; REVersed = "static_cast(reversed)"; status = "static_cast(converged() * 2)"; } device { calculated_parameters { // ordinary drain current double ids "" default=0.; double idsxxx; double gds "dids/dvds" default=0.; double gmf "dids/dvgs" default=0.; double gmr "dids/dvgd" default=0.; double gmbf "dids/dvbs" default=0.; double gmbr "dids/dvbd" default=0.; // drain-bulk double idb "" default=0.; double idbxxx "" default=0.; double gdbdb "placeholder" default=0.; double gdbds "disub/dvds" default=0.; double gdbgs "disub/dvgs" default=0.; double gdbbs "disub/dvbs" default=0.; // source-bulk double isb "" default=0.; double isbxxx "" default=0.; double gsbsb "placeholder" default=0.; double gsbsd "disub/dvds" default=0.; double gsbgd "disub/dvgs" default=0.; double gsbbd "disub/dvbs" default=0.; // charge double qgate "raw" default=0.; double cgs "dqgate_vgs placeholder" default=0.; double cggb "dqgate_vgb" default=0.; double cgsb "dqgate_vsb" default=0.; double cgdb "dqgate_vdb" default=0.; double qgs "forward mode" default=0.; double cgsgs "dqgs_vgs placeholder" default=0.; double cgsgb "dqgs_vgb" default=0.; double cgssb "dqgs_vsb" default=0.; double cgsdb "dqgs_vdb" default=0.; double qgd "reverse mode" default=0.; double cgdgd "dqgd_vgs placeholder" default=0.; double cgdgb "dqgd_vgb" default=0.; double cgdsb "dqgd_vsb" default=0.; double cgddb "dqgd_vdb" default=0.; double qdrn "Qds" default=0.; double cdsds "dqds_vds placeholder" default=0.; double cdgb "dqds_vgb" default=0.; double cdsb "dqds_vsb" default=0.; double cddb "dqds_vdb" default=0.; double qbulk "raw" default=0.; double cbs "dqbs_vbs placeholder" default=0.; double cbgb "dqbs_vbg" default=0.; double cbsb "dqbs_vsb" default=0.; double cbdb "dqbs_vdb" default=0.; double qbs "Qbs forward" default=0.; double cbsbs "dqbs_vbs placeholder" default=0.; double cbsgb "dqbs_vbg" default=0.; double cbssb "dqbs_vsb" default=0.; double cbsdb "dqbs_vdb" default=0.; double qbd "Qbd reverse" default=0.; double cbdbd "dqbd_vbd placeholder" default=0.; double cbdgb "dqbd_vbg" default=0.; double cbdsb "dqbd_vsb" default=0.; double cbddb "dqbd_vdb" default=0.; double gtau "" default=0.; double cqgb "" default=0.; double cqsb "" default=0.; double cqdb "" default=0.; double cqbb "" default=0.; /* double tconst "" default=0.; double cgb "placeholder" default=0.; // capacitors and charges double qgb "placeholder" default=0.; double qgd "" default=0.; double cgd "" default=0.; double qgs "" default=0.; //double cgs "" default=0.; */ double vgs "terminal voltages" default=0.; double vds "" default=0.; double vbs "" default=0.; double vdsat "saturation voltage" default=0.; double vgst "vgs - von." default=0.; double von "actual threshold voltage" default=0.; bool reversed "flag: Vgs < 0, reverse s & d" default=false; bool cutoff "flag: in cut off region" default=false; bool subthreshold "flag: subthreshold region" default=false; bool saturated "flag: in saturation region" default=false; bool sbfwd "flag: sb diode fwd biased" default=false; bool punchthru "flag: punch thru region" default=false; } } common { raw_parameters { double l_in "drawn (optical) channel length" name=L positive default="OPT::defl"; double w_in "channel width (drawn)" name=W positive default="OPT::defw"; double ad_in "drain area, drawn" name=AD positive default="OPT::defad" print_test="has_hard_value(ad_in)"; double as_in "source area, drawn" name=AS positive default="OPT::defas" print_test="has_hard_value(as_in)"; double pd "drain perimeter" name=PD positive default=0.0 print_test="has_hard_value(pd)"; double ps "source perimeter" name=PS positive default=0.0 print_test="has_hard_value(ps)"; double nrd "drain # squares" name=NRD positive default=1.0 print_test="has_hard_value(nrd)"; double nrs "source # squares" name=NRS positive default=1.0 print_test="has_hard_value(nrs)"; } } tr_eval { int foo=3; } /*--------------------------------------------------------------------*/ eval Cgb { STORAGE* brh = prechecked_cast(d); assert(brh); double cap = brh->value(); if (m->cmodel != 0) { if (p->vgst < - s->phi) { /* accumulation */ cap += s->cgate; }else if (p->vgst < 0.) { /* depletion */ cap += s->cgate * (-p->vgst) / s->phi; }else{ /* active, overlap only */ } } brh->_y[0].f1 = cap; if (d->_sim->analysis_is_tran_dynamic()) { cap = (brh->_y[0].f1 + brh->_y[1].f1) / 2; brh->_y[0].f0 = (brh->_y[0].x - brh->_y[1].x) * cap + brh->_y[1].f0; }else{ assert(d->_sim->analysis_is_static() || d->_sim->analysis_is_restore()); brh->_y[0].f0 = brh->_y[0].x * brh->_y[0].f1; } trace3(brh->long_label().c_str(), brh->_y[0].x, brh->_y[0].f0, brh->_y[0].f1); } /*--------------------------------------------------------------------*/ eval Cgd { STORAGE* brh = prechecked_cast(d); assert(brh); double cap = 0; if (m->cmodel != 0) { assert(p->vdsat >= 0.); assert(p->vds >= 0.); double vbs = (m->cmodel == 3) ? 0. : p->vbs; double vdbsat = p->vdsat - vbs; double vdb = p->vds - vbs; double ddif = 2. * vdbsat - vdb; if (!p->reversed) { // treat as Cgs if (p->vgst >= 0.) { if (p->vdsat > p->vds) { /* linear */ cap = (2./3.) * s->cgate * (1. - (vdbsat*vdbsat)/(ddif*ddif)); if (p->vgst <= .1) { cap *= 10. * p->vgst; // smooth discontinuity } } } }else{ // treat as Cgs if (p->vgst >= -s->phi/2.) { /* depletion or active */ cap = (2./3.) * s->cgate; if (p->vdsat > p->vds) { /* linear */ double ndif = p->vdsat - p->vds; cap *= 1. - (ndif*ndif)/(ddif*ddif); } if (p->vgst <= 0) { cap *= 1. + p->vgst / (s->phi); cap *= 1. + p->vgst / (s->phi); } } } } cap += brh->value(); /* else overlap only */ brh->_y[0].f1 = cap; if (d->_sim->analysis_is_tran_dynamic()) { cap = (brh->_y[0].f1 + brh->_y[1].f1) / 2; brh->_y[0].f0 = (brh->_y[0].x - brh->_y[1].x) * cap + brh->_y[1].f0; }else{ assert(d->_sim->analysis_is_static() || d->_sim->analysis_is_restore()); brh->_y[0].f0 = brh->_y[0].x * brh->_y[0].f1; } trace3(brh->long_label().c_str(), brh->_y[0].x, brh->_y[0].f0, brh->_y[0].f1); } /*--------------------------------------------------------------------*/ eval Cgs { STORAGE* brh = prechecked_cast(d); assert(brh); double cap = 0; if (m->cmodel != 0) { assert(p->vdsat >= 0.); assert(p->vds >= 0.); double vbs = (m->cmodel == 3) ? 0. : p->vbs; double vdbsat = p->vdsat - vbs; double vdb = p->vds - vbs; double ddif = 2. * vdbsat - vdb; if (p->reversed) { // treat as Cgd if (p->vgst >= 0.) { if (p->vdsat > p->vds) { /* linear */ cap = (2./3.) * s->cgate * (1. - (vdbsat*vdbsat)/(ddif*ddif)); if (p->vgst <= .1) { cap *= 10. * p->vgst; // smooth discontinuity } } } }else{ // treat as Cgs if (p->vgst >= -s->phi/2.) { /* depletion or active */ cap = (2./3.) * s->cgate; if (p->vdsat > p->vds) { /* linear */ double ndif = p->vdsat - p->vds; cap *= 1. - (ndif*ndif)/(ddif*ddif); } if (p->vgst <= 0) { cap *= 1. + p->vgst / (s->phi); cap *= 1. + p->vgst / (s->phi); } } } } cap += brh->value(); /* else overlap only */ brh->_y[0].f1 = cap; if (d->_sim->analysis_is_tran_dynamic()) { cap = (brh->_y[0].f1 + brh->_y[1].f1) / 2; brh->_y[0].f0 = (brh->_y[0].x - brh->_y[1].x) * cap + brh->_y[1].f0; }else{ assert(d->_sim->analysis_is_static() || d->_sim->analysis_is_restore()); brh->_y[0].f0 = brh->_y[0].x * brh->_y[0].f1; } trace3(brh->long_label().c_str(), brh->_y[0].x, brh->_y[0].f0, brh->_y[0].f1); } /*--------------------------------------------------------------------*/ function reverse_if_needed() { if (vds < 0) { error(bTRACE, long_label() + ": reversing\n"); error(bTRACE, "before: vds=%g vgs=%g vbs=%g\n", vds, vgs, vbs); reversed = !reversed; vgs -= vds; vbs -= vds; vds = -vds; error(bTRACE, "after: vds=%g vgs=%g vbs=%g\n", vds, vgs, vbs); if (OPT::dampstrategy & dsREVERSE) { _sim->_fulldamp = true; untested(); error(bTRACE, long_label() + ":reverse damp\n"); } if (!(OPT::mosflags & 0040)) { vbs = std::min(vbs,0.); }else{ untested(); } } } /*--------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ cc_direct { /*--------------------------------------------------------------------------*/ bool DEV_BUILT_IN_MOS::tr_needs_eval()const { if (is_q_for_eval()) { untested(); return false; }else if (!converged()) { return true; }else{ const COMMON_BUILT_IN_MOS* c = prechecked_cast(common()); assert(c); const MODEL_BUILT_IN_MOS_BASE* m=prechecked_cast(c->model()); assert(m); polarity_t polarity = m->polarity; node_t& eff_s((reversed) ? _n[n_id] : _n[n_is]); node_t& eff_d((reversed) ? _n[n_is] : _n[n_id]); return !(conchk(vds,polarity*(eff_d.v0()-eff_s.v0()),OPT::vntol) && conchk(vgs, polarity*(_n[n_g].v0()-eff_s.v0()), OPT::vntol) && conchk(vbs, polarity*(_n[n_b].v0()-eff_s.v0()), OPT::vntol)); } } /*--------------------------------------------------------------------------*/ bool DEV_BUILT_IN_MOS::do_tr() { const COMMON_BUILT_IN_MOS* c = prechecked_cast(common()); assert(c); const MODEL_BUILT_IN_MOS_BASE* m = prechecked_cast(c->model()); assert(m); bool was_cutoff = cutoff; bool was_subthreshold = subthreshold; bool was_saturated = saturated; bool was_reversed = reversed; bool was_sbfwd = sbfwd; polarity_t polarity = m->polarity; if (_sim->is_initial_step()) { reversed = false; vds = vgs = vbs = 0.; }else{ double Vds, Vgs, Vbs; if (reversed) { Vds = polarity * volts_limited(_n[n_is],_n[n_id]); Vgs = polarity * volts_limited(_n[n_g],_n[n_id]); Vbs = polarity * volts_limited(_n[n_b],_n[n_id]); }else{ Vds = polarity * volts_limited(_n[n_id],_n[n_is]); Vgs = polarity * volts_limited(_n[n_g],_n[n_is]); Vbs = polarity * volts_limited(_n[n_b],_n[n_is]); } vgs = fet_limit_vgs(Vgs, vgs, von); if (_n[n_d].n_() == _n[n_g].n_()) { vds = Vds + (vgs - Vgs); }else{ // Spice hacks Vds here, but my tests show that it often makes // convergence worse, and never improves it. // I am guessing that it does help when drain and gate are connected, // and Spice does it here in case they are and cannot be determined // whether they are or not. // The hack maintains Vdg after Vgs limiting. //Vds = Vds + (vgs - Vgs); vds = fet_limit_vds(Vds, vds); } vbs = std::min(Vbs, 0.); //vbs = pnj_limit(double Vbs, double vbs, double vt, double vcrit); //vds = Vds; //vgs = Vgs; //vbs = Vbs; } assert(qgate == qgate); assert(qgs == qgs); assert(qgd == qgd); assert(qdrn == qdrn); assert(qbulk == qbulk); assert(qbs == qbs); assert(qbd == qbd); m->tr_eval(this); assert(qgate == qgate); assert(qgs == qgs); assert(qgd == qgd); assert(qdrn == qdrn); assert(qbulk == qbulk); assert(qbs == qbs); assert(qbd == qbd); if (reversed) { idsxxx = ids + vds*gds + vgs*gmr + vbs*gmbr; isbxxx = isb - vds*gsbsd - vgs*gsbgd - vbs*gsbbd; idbxxx = 0.; }else{ idsxxx = ids - vds*gds - vgs*gmf - vbs*gmbf; idbxxx = idb - vds*gdbds - vgs*gdbgs - vbs*gdbbs; isbxxx = 0.; } ids *= polarity; idsxxx *= polarity; assert(subckt()); set_converged(subckt()->do_tr()); trace3(long_label().c_str(), vds, vgs, vbs); trace4("", ids, gmf, gds, gmbf); trace4("", ids, gmr, gds, gmbr); if (was_cutoff != cutoff || was_subthreshold != subthreshold || was_saturated != saturated || was_reversed != reversed || was_sbfwd != sbfwd) { if (OPT::dampstrategy & dsDEVREGION) { _sim->_fulldamp = true; }else{ } #if defined(DO_TRACE) error(bTRACE,"%s:%d: region change\n", long_label().c_str(), evaliter()); #endif }else{ } return converged(); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ����������������������������������������������������������������src/d_mos1.model������������������������������������������������������������������������������������0000664�0000000�0000000�00000013442�11454012162�0014051�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: d_mos1.model,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * mos model equations: spice level 1 equivalent */ h_headers { #include "d_mos123.h" } cc_headers { } /*--------------------------------------------------------------------------*/ model BUILT_IN_MOS1 { level 1; public_keys { nmos1 polarity=pN; pmos1 polarity=pP; nmos polarity=pN; pmos polarity=pP; } dev_type BUILT_IN_MOS; inherit BUILT_IN_MOS123; independent { override { double mjsw "" default=.5; double cox "" final_default=0.; double vto "" final_default=0.; double gamma "" final_default=0.; double phi "" final_default=.6; int mos_level "back-annotate for diode" name=DIODElevel print_test="mos_level != LEVEL" default=LEVEL; } raw_parameters { double kp "transconductance parameter" name=KP final_default=2e-5 print_test="!calc_kp" calc_print_test="calc_kp"; } calculated_parameters { bool calc_kp "" default=false; } code_pre { if (tox != NA) { cox = P_EPS_OX / tox; if (kp == NA) { kp = uo * cox; calc_kp = true; } if (nsub != NA) { if (phi == NA) { phi = (2. * P_K_Q) * tnom_k * log(nsub/NI); if (phi < .1) { untested(); error(((!_sim->is_first_expand()) ? (bDEBUG) : (bWARNING)), long_label() + ": calculated phi too small, using .1\n"); phi = .1; } calc_phi = true; } if (gamma == NA) { gamma = sqrt(2. * P_EPS_SI * P_Q * nsub) / cox; calc_gamma = true; } if (vto == NA) { double phi_ms = (tpg == gtMETAL) ? polarity * (-.05 - (egap + polarity * phi) / 2.) : -(tpg * egap + phi) / 2.; double vfb = phi_ms - polarity * P_Q * nss / cox; vto = vfb + phi + gamma * sqrt(phi); calc_vto = true; } }else{ // tox is input, nsub isn't } } } } temperature_dependent { calculated_parameters { double phi "" calculate="m->phi*tempratio + (-2*vt*(1.5*log(tempratio)+P_Q*(arg)))"; double beta "" calculate="(m->kp / tempratio4) * s->w_eff / s->l_eff"; double sqrt_phi "" calculate="sqrt(phi)"; double egap "" calculate="egap_"; } code_pre { double temp = d->_sim->_temp_c + P_CELSIUS0; double tempratio = temp / m->tnom_k; double tempratio4 = tempratio * sqrt(tempratio); double kt = temp * P_K; double vt = temp * P_K_Q; double egap_ = 1.16 - (7.02e-4*temp*temp) / (temp+1108.); double arg = (m->egap*tempratio - egap_) / (2*kt); } } /*-----------------------------------------------------------------------*/ tr_eval { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ trace0(d->long_label().c_str()); trace3("", d->vds, d->vgs, d->vbs); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ d->reverse_if_needed(); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ double sarg, dsarg_dvbs; { if (d->vbs <= 0.) { sarg = sqrt(t->phi - d->vbs); dsarg_dvbs = -.5 / sarg; d->sbfwd = false; trace2("sb-ok", sarg, dsarg_dvbs); }else{ untested(); sarg = t->sqrt_phi / (1. + .5 * d->vbs / t->phi); dsarg_dvbs = -.5 * sarg * sarg / t->phi*t->sqrt_phi; /* is wrong!! */ d->sbfwd = true; trace2("***sb-reversed***", sarg, dsarg_dvbs); } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ d->von = m->vto + m->gamma * (sarg - sqrt(m->phi)) + .5 * (m->egap - t->egap) + .5 * (t->phi - m->phi); d->vgst = d->vdsat = d->vgs - d->von; if (d->vdsat < 0.) { d->vdsat = 0.; } d->cutoff = (d->vgst < 0.); d->saturated = (d->vds > d->vdsat); trace3("", d->von, d->vgst, d->vdsat); double Lambda = (m->lambda != NA) ? m->lambda : 0.; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (d->cutoff) { d->gds = d->gmf = d->ids = d->gmbf = 0.; trace4("cut", d->ids, d->gmf, d->gds, d->gmbf); }else if (d->saturated) { d->gmf = t->beta * d->vgst * (1. + Lambda * d->vds); d->ids = d->gmf * (.5 * d->vgst); d->gds = .5 * t->beta * Lambda * d->vgst * d->vgst; d->gmbf = - d->gmf * m->gamma * dsarg_dvbs; trace4("sat", d->ids, d->gmf, d->gds, d->gmbf); }else{ /* triode */ d->gmf = t->beta * d->vds * (1. + Lambda * d->vds); d->ids = d->gmf * (d->vgst - .5*d->vds); d->gds = t->beta * ((d->vgst - d->vds) + Lambda * d->vds * (2.*d->vgst - 1.5*d->vds)); d->gmbf = -d->gmf * m->gamma * dsarg_dvbs; trace4("lin", d->ids, d->gmf, d->gds, d->gmbf); } if (d->reversed) { d->ids *= -1; d->gmr = d->gmf; d->gmbr = d->gmbf; d->gmf = d->gmbf = 0; }else{ d->gmr = d->gmbr = 0.; } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_mos123.model����������������������������������������������������������������������������������0000664�0000000�0000000�00000007652�11454012162�0014224�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: d_mos123.model,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * MOS model - base for levels 1,2,3,6 */ h_headers { #include "d_mos_base.h" enum gate_t {gtSAME = -1, gtMETAL = 0, gtOPP = 1}; const double NI = 1.45e16; /* intrinsic carrier concentration */ } cc_headers { } /*--------------------------------------------------------------------------*/ model BUILT_IN_MOS123 { dev_type BUILT_IN_MOS; inherit BUILT_IN_MOS_BASE; independent { override { double cjo "" default=0.; double pb "" default=0.8; double pbsw "" final_default=pb; int cmodel "CMODEL" print_test="cmodel!=3" calculate="((!cmodel)?3:cmodel)"; } raw_parameters { double vto_raw "zero-bias threshold voltage" name=VTO default=NA print_test="!calc_vto"; double gamma "bulk threshold parameter" name=GAmma default=NA print_test="!calc_gamma" calc_print_test="calc_gamma"; double phi "surface potential" name=PHI default=NA positive print_test="!calc_phi" calc_print_test="calc_phi"; double lambda "channel-length modulation" name=LAmbda default=NA; double tox "oxide thickness" name=TOX default=NA positive; double nsub_cm "substrate doping" name=NSUb default=NA; double nss_cm "surface state density" name=NSS default=0.0 print_test="nss_cm != 0.0 || has_hard_value(nsub_cm)"; double xj "metallurgical junction depth" name=XJ default=NA positive; double uo_cm "surface mobility" name=UO alt_name=U0 default="600."; int tpg "type of gate material - really gate_t" name=TPG default="int(gtOPP)"; } calculated_parameters { double nsub "" calculate="((nsub_cm.has_hard_value()) ? nsub_cm*ICM2M3 : NA)"; double nss "" calculate="nss_cm*ICM2M2"; double uo "" calculate="uo_cm*CM2M2"; double vto "" name=VTO calculate="((vto_raw.has_hard_value()) ? vto_raw * polarity : NA)" calc_print_test="calc_vto"; double cox "oxide capacitance (E_OX / tox)" name=COX calc_print_test=true default=NA; bool calc_vto "" default=false; bool calc_gamma "" default=false; bool calc_phi "" default=false; } code_post { if (tpg < 0) { // coerce tpg to a proper value tpg = gtSAME; }else if (tpg > 0) { tpg = gtOPP; }else{ assert(tpg == gtMETAL); } if (has_hard_value(tox) && tox <= 0) { untested(); set_default(&tox, NA); error(((!_sim->is_first_expand()) ? (bDEBUG) : (bWARNING)), long_label()+": tox <= 0, treating as if not input\n"); } if (has_hard_value(nsub_cm) && nsub < NI) { untested(); nsub = NA; error(((!_sim->is_first_expand()) ? (bDEBUG) : (bWARNING)), long_label()+": nsub < ni, treating as if not input\n"); } } } size_dependent { override { double cgate "" calculate="m->cox * w_eff * l_eff"; double phi "" calculate="m->phi"; } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������src/d_mos2.model������������������������������������������������������������������������������������0000664�0000000�0000000�00000053302�11454012162�0014051�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: d_mos2.model,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * mos model equations: spice level 2 equivalent */ h_headers { #include "d_mos123.h" } cc_headers { #include "l_compar.h" #include "l_denoise.h" } /*--------------------------------------------------------------------------*/ model BUILT_IN_MOS2 { level 2; public_keys { nmos2 polarity=pN; pmos2 polarity=pP; } dev_type BUILT_IN_MOS; inherit BUILT_IN_MOS123; independent { override { double mjsw "" default=.33; double tox "" default=1e-7; double cox "" final_default="P_EPS_OX/tox"; double vto "" final_default=0.0; double gamma "" final_default=0.0; double phi "" final_default=0.6; int mos_level "back-annotate for diode" name=DIODElevel print_test="mos_level != LEVEL" default=LEVEL; } raw_parameters { double kp "transconductance parameter" name=KP final_default=2e-5 print_test="!calc_kp" calc_print_test="calc_kp"; double nfs_cm "fast surface state density" name=NFS default=0.0; double vmax "max drift velocity of carriers" name=VMAx default=NA; double neff "total channel charge coefficient" name=NEFf default=1.0 positive print_test="neff != 1.0 || lambda == NA"; double ucrit_cm "critical field mobility degradation" name=UCRit default=1e4 print_test="ucrit_cm != 1e4 || uexp != NA"; double uexp "critical field exponent in mob.deg." name=UEXp default=NA; double utra "transverse field coefficient (not used)" name=UTRa default=NA print_test=false; double delta "width effect on threshold voltage" name=DELta default=0.0; } calculated_parameters { double nfs "" calculate="nfs_cm*ICM2M2"; double ucrit "" calculate="ucrit_cm*ICM2M"; bool calc_kp "" default=false; double alpha "" calculate="((nsub != NA) ? (2. * P_EPS_SI) / (P_Q * nsub) : 0.)"; double xd "coeffDepLayWidth" calculate="sqrt(alpha)"; double xwb "" calculate="((nsub != NA) ? xd * sqrt(pb) : .25e-6)"; double vbp "" calculate="ucrit * P_EPS_SI / cox"; double cfsox "" calculate="P_Q * nfs / cox"; } code_pre { if (!has_good_value(tox)) { tox = 1e-7; } cox = P_EPS_OX / tox; if (kp == NA) { kp = uo * cox; calc_kp = true; } if (nsub != NA) { if (phi == NA) { phi = (2. * P_K_Q) * tnom_k * log(nsub/NI); if (phi < .1) { untested(); error(((!_sim->is_first_expand()) ? (bDEBUG) : (bWARNING)), long_label() + ": calculated phi too small, using .1\n"); phi = .1; } calc_phi = true; } if (gamma == NA) { gamma = sqrt(2. * P_EPS_SI * P_Q * nsub) / cox; calc_gamma = true; } if (vto == NA) { double phi_ms = (tpg == gtMETAL) ? polarity * (-.05 - (egap + polarity * phi) / 2.) : -(tpg * egap + phi) / 2.; double vfb = phi_ms - polarity * P_Q * nss / cox; vto = vfb + phi + gamma * sqrt(phi); calc_vto = true; } } } } size_dependent { calculated_parameters { double relxj "" calculate="((m->xj != NA && m->xj > 0) ? .5 * m->xj / l_eff : NA)"; double eta_1 "" calculate="((cgate != 0) ? M_PI_4 * P_EPS_SI * m->delta / cgate * l_eff : 0.)"; double eta "" calculate="eta_1 + 1."; double eta_2 "" calculate="eta / 2."; } } temperature_dependent { calculated_parameters { double vt "" calculate="temp * P_K_Q"; double phi "" calculate="m->phi*tempratio + (-2*vt*(1.5*log(tempratio)+P_Q*(arg)))"; double sqrt_phi "" calculate="sqrt(phi)"; double phi_sqrt_phi "" calculate="phi * sqrt_phi"; double beta "" calculate="(m->kp / tempratio4) * s->w_eff / s->l_eff"; double uo "" calculate="m->uo * tempratio4"; double vbi "" calculate="(fixzero( (m->vto - m->gamma * sqrt(m->phi) +.5*(m->egap-egap) + m->polarity* .5 * (phi-m->phi)), m->phi))"; } code_pre { double temp = d->_sim->_temp_c + P_CELSIUS0; double tempratio = temp / m->tnom_k; // ratio double tempratio4 = tempratio * sqrt(tempratio); double kt = temp * P_K; double egap = 1.16 - (7.02e-4*temp*temp) / (temp+1108.); double arg = (m->egap*tempratio - egap) / (2*kt); } } /*-----------------------------------------------------------------------*/ tr_eval { #define short_channel (m->xj != NOT_INPUT && m->xj > 0.) #define do_subthreshold (m->nfs != 0.) /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ trace1(d->long_label().c_str(), d->evaliter()); trace3("", d->vds, d->vgs, d->vbs); assert(m->tnom_k > 0); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ d->reverse_if_needed(); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ double v_phi_s = t->phi - d->vbs; double sarg, dsarg_dvbs, d2sdb2, sarg3; { if (d->vbs <= 0.) { sarg = sqrt(v_phi_s); dsarg_dvbs = -.5 / sarg; d2sdb2 = .5 * dsarg_dvbs / v_phi_s; d->sbfwd = false; trace3("sb-ok", sarg, v_phi_s, dsarg_dvbs); }else{ if (OPT::mosflags & 01000) { sarg = t->sqrt_phi / (1. + .5 * d->vbs / t->phi); dsarg_dvbs = -.5 * sarg * sarg / t->phi_sqrt_phi; d2sdb2 = -dsarg_dvbs * sarg / t->phi_sqrt_phi; untested(); trace3("***sb-reversed(01000)***", sarg, v_phi_s, dsarg_dvbs); }else{ sarg = t->sqrt_phi / (1. + .5 * d->vbs / t->phi + .375 * d->vbs * d->vbs / (t->phi * t->phi)); dsarg_dvbs = (-.5 * sarg * sarg / t->phi_sqrt_phi) * (1. + 1.5 * d->vbs / t->phi); d2sdb2 = (-dsarg_dvbs * sarg / t->phi_sqrt_phi) - (.75 * sarg / (t->phi_sqrt_phi * t->phi)) * (2. * d->vbs * dsarg_dvbs + sarg); untested(); trace3("***sb-reversed(00000)***", sarg, v_phi_s, dsarg_dvbs); } d->sbfwd = true; } sarg3 = sarg*sarg*sarg; assert(sarg > 0.); assert(dsarg_dvbs < 0.); assert(up_order(-1/t->phi, d2sdb2, 1/t->phi)); trace2("", d2sdb2, sarg3); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ double barg, dbarg_dvbs, d2bdb2; { double vbd = d->vbs - d->vds; double v_phi_d = t->phi - vbd; if (vbd <= 0.) { barg = sqrt(v_phi_d); dbarg_dvbs = -.5 / barg; d2bdb2 = .5 * dbarg_dvbs / v_phi_d; //d->dbfwd = false; trace4("db-ok", barg, v_phi_d, dbarg_dvbs, d2bdb2); }else{ if (OPT::mosflags & 01000) { barg = t->sqrt_phi / (1. + .5 * vbd / t->phi); dbarg_dvbs = -.5 * barg * barg / t->phi_sqrt_phi; d2bdb2 = -dbarg_dvbs * barg / t->phi_sqrt_phi; untested(); trace4("***db-reversed(00000)***",barg, v_phi_d, dbarg_dvbs, d2bdb2); }else{ barg = t->sqrt_phi / (1. + .5 * vbd / t->phi + .375 * vbd * vbd / (t->phi * t->phi)); dbarg_dvbs = (-.5 * barg * barg / t->phi_sqrt_phi) * (1. + 1.5 * vbd / t->phi); d2bdb2 = (-dbarg_dvbs * barg / t->phi_sqrt_phi) - (.75 * barg / (t->phi_sqrt_phi * t->phi)) * (2. * vbd * dbarg_dvbs + barg); trace4("***db-reversed(00000)***",barg, v_phi_d, dbarg_dvbs, d2bdb2); } //d->dbfwd = true; } assert(barg > 0.); assert(dbarg_dvbs < 0.); assert(up_order(-1/t->phi, d2bdb2, 1/t->phi)); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ double gamma_s, dgamma_s_dvds, dgamma_s_dvbs, dgddb2; { if (short_channel) { double argxd = 1. + 2. * barg * m->xd / m->xj; assert(argxd > 0); double argd = sqrt(argxd); trace2("", argxd, argd); double alpha_d = s->relxj * (argd - 1.); double dalpha_d_dvds = m->xd / (4. * s->l_eff * argd * barg); double dalpha_d_dvbs = -dalpha_d_dvds; trace3("", alpha_d, dalpha_d_dvds, dalpha_d_dvbs); double argxs = 1. + 2. * sarg * m->xd / m->xj; assert(argxs > 0); double args = sqrt(argxs); trace2("", argxs, args); double alpha_s = s->relxj * (args - 1.); double dalpha_s_dvbs = -m->xd / (4. * s->l_eff * args * sarg); trace2("", alpha_s, dalpha_s_dvbs); gamma_s = m->gamma * (1. - alpha_s - alpha_d); dgamma_s_dvds = -m->gamma * dalpha_d_dvds; dgamma_s_dvbs = -m->gamma * (dalpha_d_dvbs + dalpha_s_dvbs); double dasdb2=-m->xd*(d2sdb2+dsarg_dvbs*dsarg_dvbs*m->xd/(m->xj*argxs)) / (s->l_eff*args); double daddb2=-m->xd*(d2bdb2+dbarg_dvbs*dbarg_dvbs*m->xd/(m->xj*argxd)) / (s->l_eff*argd); dgddb2 = -.5 * m->gamma * (dasdb2 + daddb2); if (gamma_s <= 0. && m->gamma > 0.) { untested(); error(bTRACE, d->long_label() + ": gamma is negative\n"); error(bTRACE, "+ gamma_s=%g, alpha_s=%g, alpha_d=%g\n", gamma_s, alpha_s, alpha_d); } trace4("no short chan", gamma_s, dgamma_s_dvds, dgamma_s_dvds, dgddb2); }else{ gamma_s = m->gamma; dgamma_s_dvds = dgamma_s_dvbs = 0.; dgddb2 = 0.; trace4("short channel", gamma_s, dgamma_s_dvds, dgamma_s_dvds, dgddb2); } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* von, subthreshold, cutoff, vgst */ double vc, vc_eta, dvon_dvbs; double xn, vtxn, dxn_dvbs; /* subthreshold only */ { double vbin = t->vbi + s->eta_1 * v_phi_s; d->von = vbin + gamma_s * sarg; dvon_dvbs = -s->eta_1 + dgamma_s_dvbs * sarg + gamma_s * dsarg_dvbs; trace3("guess", vbin, d->von, dvon_dvbs); if (do_subthreshold) { double cdonco = -(gamma_s*dsarg_dvbs + dgamma_s_dvbs*sarg) + s->eta_1; xn = 1. + m->cfsox + cdonco; vtxn = t->vt * xn; dxn_dvbs = 2. * dgamma_s_dvbs * dsarg_dvbs + gamma_s * d2sdb2 + dgddb2 * sarg; trace3("do_sub", xn, vtxn, dxn_dvbs); d->von += vtxn; dvon_dvbs += t->vt * dxn_dvbs; d->vgst = d->vgs - d->von; trace3("", d->von, dvon_dvbs, d->vgst); d->subthreshold = (d->vgs < d->von); d->cutoff = false; }else{ xn = vtxn = dxn_dvbs = 0.; d->vgst = d->vgs - d->von; trace3("no_sub", xn, vtxn, dxn_dvbs); trace3("", d->von, dvon_dvbs, d->vgst); d->subthreshold = false; d->cutoff = (d->vgs < d->von); if (d->cutoff) { trace0("***** cut off *****"); d->ids = 0.; d->gmf = d->gmr = 0.; d->gds = 0.; d->gmbf = d->gmbr = 0.; return; } } double vgsx = (d->subthreshold) ? d->von : d->vgs; vc = vgsx - vbin; vc_eta = vc / s->eta; trace3("", vgsx, vc, vc_eta); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ double ufact, duf_dvgs, duf_dvds, duf_dvbs, ueff; { if (m->uexp != NOT_INPUT && d->vgst > m->vbp) { ufact = pow(m->vbp/d->vgst, m->uexp); duf_dvgs = -ufact * m->uexp / d->vgst; duf_dvds = 0.; /* wrong, but as per spice2 */ duf_dvbs = dvon_dvbs * ufact * m->uexp / d->vgst; trace4("calc ufact", ufact, duf_dvgs, duf_dvds, duf_dvbs); }else{ ufact = 1.; duf_dvgs = duf_dvds = duf_dvbs = 0.; trace4("def ufact", ufact, duf_dvgs, duf_dvds, duf_dvbs); } ueff = t->uo * ufact; /* ???? */ trace2("", ufact, ueff); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* vdsat according to Baum's Theory of scattering velocity saturation */ int use_vmax = m->vmax != NOT_INPUT; if (use_vmax) { double gammad = gamma_s / s->eta; double v1 = vc_eta + v_phi_s; double v2 = v_phi_s; double xv = m->vmax * s->l_eff / ueff; double a1 = gammad * (4./3.); double b1 = -2. * (v1+xv); double c1 = -2. * gammad * xv; /* end of scope */ double d1 = 2.*v1*(v2+xv) - v2*v2 - (4./3.)*gammad*sarg3; double a = -b1; /* xv, v1, v2, sarg3 */ double b = a1 * c1 - 4. * d1; double C = -d1 * (a1*a1 - 4.*b1) - c1*c1; double r = -a*a / 3. + b; double r3 = r*r*r; /* r */ double S = 2. * a*a*a / 27. - a*b / 3. + C; /* b, c */ double s2 = S*S; double p = s2 / 4. + r3 / 27.; /* r */ double y3; if (p < 0.) { /* p */ double ro = pow((-r3 / 27), (1./6.)); /* s2, r3 */ double fi = atan(-2. * sqrt(-p) / S); y3 = 2. * ro * cos(fi/3.) - a / 3.; }else{ double p2 = sqrt(p); double p3 = pow((fabs(-S/2.+p2)), (1./3.)); double p4 = pow((fabs(-S/2.-p2)), (1./3.)); /* s */ y3 = p3 + p4 - a / 3.; /* a */ untested(); } double x4[8]; int iknt = 0; if (a1*a1 / 4. - b1 + y3 < 0. && y3*y3 / 4. - d1 < 0.) { untested(); error(bWARNING, "%s: internal error: a3,b4, a1=%g, b1=%g, y3=%g, d1=%g\n", d->long_label().c_str(), a1, b1, y3, d1); }else{ double a3 = sqrt(a1*a1 / 4. - b1 + y3); double b3 = sqrt(y3*y3 / 4. - d1); for (int i = 0; i < 4; i++) { static const double sig1[4] = {1., -1., 1., -1.}; static const double sig2[4] = {1., 1., -1., -1.}; double a4 = a1 / 2. + sig1[i] * a3; double b4 = y3 / 2. + sig2[i] * b3; /* y3 */ double delta4 = a4*a4 / 4. - b4; if (delta4 >= 0.) { double sd4 = sqrt(delta4); x4[iknt++] = - a4 / 2. + sd4; x4[iknt++] = - a4 / 2. - sd4; /* i */ } } } double xvalid = 0.; int root_count = 0; for (int j = 0; j < iknt; j++) { /* iknt */ if (x4[j] > 0.) { double poly4 = x4[j]*x4[j]*x4[j]*x4[j]/* ~= 0, used as check */ + a1 * x4[j]*x4[j]*x4[j] /* roundoff error not */ + b1 * x4[j]*x4[j] /* propagated, so ok */ + c1 * x4[j] + d1; /* a1, b1, c1, d1 */ if (fabs(poly4) <= 1e-6) { root_count++; if (root_count <= 1) { /* xvalid = min(x4[j]) */ xvalid=x4[j]; } if (x4[j] <= xvalid) { xvalid=x4[j]; /* x4[], j */ }else{ untested(); } } } } if (root_count <= 0) { /* root_count */ error(bTRACE, d->long_label() + ": Baum's theory rejected\n"); use_vmax = false; d->vdsat = 0.; trace1("use_vmax rejected", d->vdsat); }else{ d->vdsat = xvalid*xvalid - v_phi_s; trace1("use_vmax", d->vdsat); } }else{ d->vdsat = 0.; trace1("!use_vmax", d->vdsat); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* vdsat according to Grove-Frohman equation */ double dvdsat_dvgs = NOT_VALID; double dvdsat_dvbs = NOT_VALID; if (!use_vmax) { if (gamma_s > 0.) { double argv = vc_eta + v_phi_s; if (argv > 0.) { double gammad = gamma_s / s->eta; double gammd2 = gammad * gammad; double arg1 = sqrt(1. + 4. * argv / gammd2); d->vdsat = vc_eta + gammd2 * (1.-arg1) / 2.; dvdsat_dvgs = (1. - 1./arg1) / s->eta; dvdsat_dvbs = (gammad * (1.-arg1) + 2.*argv / (gammad*arg1)) / s->eta * dgamma_s_dvbs + 1./arg1 + s->eta_1 * dvdsat_dvgs; trace3("!use_vmax,gamma>0,argv>0",d->vdsat,dvdsat_dvgs,dvdsat_dvbs); }else{ untested(); d->vdsat = 0.; dvdsat_dvgs = dvdsat_dvbs = 0.; error(bTRACE, d->long_label() + ": argv is negative\n"); trace2("argv<0", argv, vc); trace3("!use_vmax,gamma>0,argv<=0",d->vdsat,dvdsat_dvgs,dvdsat_dvbs); } }else{ d->vdsat = vc_eta; dvdsat_dvgs = 1.; dvdsat_dvbs = 0.; trace3("!use_vmax, gamma<=0", d->vdsat, dvdsat_dvgs, dvdsat_dvbs); } }else{ /* dvdsat_dvgs, dvdsat_dvbs deferred */ trace3("use_vmax", d->vdsat, dvdsat_dvgs, dvdsat_dvbs); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (d->vdsat < 0.) { error(bWARNING, "%s: calculated vdsat (%g) < 0. using vdsat = 0.\n", d->long_label().c_str(), d->vdsat); d->vdsat = 0.; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ double bsarg, dbsarg_dvbs; { double vbdsat = d->vbs - d->vdsat; if (vbdsat <= 0.) { double v_phi_ds = t->phi - vbdsat; bsarg = sqrt(v_phi_ds); dbsarg_dvbs = -.5 / bsarg; trace3("vbdsat <= 0", vbdsat, bsarg, dbsarg_dvbs); }else{ bsarg = t->sqrt_phi / (1. + .5 * vbdsat / t->phi); dbsarg_dvbs = -.5 * bsarg * bsarg / t->phi_sqrt_phi; untested(); trace3("vbdsat > 0", vbdsat, bsarg, dbsarg_dvbs); } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* local dvdsat_dvgs, dvdsat_dvbs maybe */ { if (use_vmax) { double bodys = bsarg*bsarg*bsarg - sarg3; double gdbdvs = 2. * gamma_s * (bsarg*bsarg*dbsarg_dvbs - sarg*sarg*dsarg_dvbs); double argv = vc_eta - d->vdsat; double vqchan = argv - gamma_s * bsarg; double dqdsat = -1. + gamma_s * dbsarg_dvbs; double vl = m->vmax * s->l_eff; double dfunds = vl * dqdsat - ueff * vqchan; double dfundg = (vl - ueff * d->vdsat) / s->eta; double dfundb = -vl * (1. + dqdsat - s->eta_1 / s->eta) + ueff * (gdbdvs - dgamma_s_dvbs * bodys / 1.5) / s->eta; dvdsat_dvgs = -dfundg / dfunds; dvdsat_dvbs = -dfundb / dfunds; trace2("use_vmax", dvdsat_dvgs, dvdsat_dvbs); }else{ /* dvdsat_dvgs, dvdsat_dvbs already set */ trace2("!use_vmax", dvdsat_dvgs, dvdsat_dvbs); } assert(dvdsat_dvgs != NOT_VALID); assert(dvdsat_dvbs != NOT_VALID); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ double dl_dvgs, dl_dvds, dl_dvbs, clfact; { if (d->vds >= 0.) { if (m->lambda == NOT_INPUT) { double dldsat; if (use_vmax) { double xdv = m->xd / sqrt(m->neff); double xlv = m->vmax * xdv / (2. * ueff); double argv = d->vds - d->vdsat; if (argv < 0.) { argv = 0.; } double xls = sqrt(xlv*xlv + argv); double dl = (xls-xlv) * xdv; /* lambda = dl / (s->l_eff * d->vds); */ clfact = (1. - dl / s->l_eff); dldsat = xdv / (2. * xls * s->l_eff); }else{ double argv = (d->vds - d->vdsat) / 4.; double sargv = sqrt(1. + argv*argv); if (argv + sargv >= 0.) { double dl = m->xd * sqrt(argv + sargv); /* lambda = dl / (s->l_eff * d->vds); */ clfact = (1. - dl / s->l_eff); /* dldsat = lambda * d->vds / (8. * sargv); */ dldsat = dl / (s->l_eff * 8. * sargv); }else{ /* lambda = 0.; */ clfact = 1.; dldsat = 0.; untested(); error(bWARNING, "%s: internal error: vds(%g) < vdsat(%g)\n", d->long_label().c_str(), d->vds, d->vdsat); } } dl_dvgs = dvdsat_dvgs * dldsat; dl_dvds = - dldsat; dl_dvbs = dvdsat_dvbs * dldsat; }else{ /* lambda = m->lambda; */ clfact = (1. - m->lambda * d->vds); dl_dvgs = dl_dvbs = 0.; dl_dvds = -m->lambda; } /* clfact = (1. - lambda * d->vds); */ if (clfact < m->xwb/s->l_eff) { double leff = m->xwb / (2. - (clfact * s->l_eff / m->xwb)); double dfact = (leff * leff) / (m->xwb * m->xwb); clfact = leff / s->l_eff; dl_dvgs *= dfact; dl_dvds *= dfact; dl_dvbs *= dfact; } }else{ /* vds <= 0. */ /* lambda = 0.; */ clfact = 1.; dl_dvgs = dl_dvds = dl_dvbs = 0.; trace1("*** vds < 0 ***", d->vds); } trace4("", dl_dvgs, dl_dvds, dl_dvbs, clfact); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* ids, gmf, gds, gmbf */ { d->saturated = (d->vds > d->vdsat); double vdsx = (d->saturated) ? d->vdsat : d->vds; double bargx = (d->saturated) ? bsarg : barg; double body = bargx*bargx*bargx - sarg3; double expg = (d->subthreshold) ? exp(d->vgst / vtxn) : 1.; trace4("", vdsx, bargx, body, expg); trace3("", t->beta, ufact, clfact); double beta = t->beta * ufact / clfact; double ids_on = beta * ((vc - s->eta_2 * vdsx) * vdsx - (2./3.) * gamma_s * body); trace4("", beta, vc, (s->eta*vdsx), (gamma_s*bargx)); double didvds = beta * (vc - s->eta * vdsx - gamma_s * bargx); fixzero(&didvds, ids_on); trace4("", beta, ids_on, didvds, d->saturated); d->ids = ids_on * expg; d->gmf = beta * vdsx; d->gmf += ids_on * (duf_dvgs/ufact - dl_dvgs/clfact); if (d->saturated) { d->gmf += didvds * dvdsat_dvgs; } if (d->subthreshold) { d->gmf = ids_on / vtxn; if (d->saturated) { d->gmf += didvds * dvdsat_dvgs; } d->gmf *= expg; } d->gds = (d->saturated) ? 0.: didvds; d->gds += ids_on * (duf_dvds/ufact - dl_dvds/clfact); if (short_channel) { d->gds -= beta * (2./3.) * body * dgamma_s_dvds; } if (d->subthreshold) { double dxndvd = dgamma_s_dvds * dsarg_dvbs; double dodvds = dgamma_s_dvds * sarg + t->vt * dxndvd; double gmw = d->ids * d->vgst / (vtxn * xn); d->gds *= expg; d->gds -= d->gmf * dodvds + gmw * dxndvd; } d->gmbf = beta * (s->eta_1 * vdsx - gamma_s * (sarg - bargx)); d->gmbf += ids_on * (duf_dvbs/ufact - dl_dvbs/clfact); if (short_channel) { d->gmbf -= beta * (2./3.) * body * dgamma_s_dvbs; } if (d->saturated) { d->gmbf += didvds * dvdsat_dvbs; } if (d->subthreshold) { double gmw = d->ids * d->vgst / (vtxn * xn); d->gmbf += beta * dvon_dvbs * vdsx; d->gmbf *= expg; d->gmbf -= d->gmf * dvon_dvbs + gmw * dxn_dvbs; } trace4("", d->ids, d->gmf, d->gds, d->gmbf); } if (d->reversed) { d->ids *= -1; d->gmr = d->gmf; d->gmbr = d->gmbf; d->gmf = d->gmbf = 0; }else{ d->gmr = d->gmbr = 0.; } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_mos3.model������������������������������������������������������������������������������������0000664�0000000�0000000�00000037235�11454012162�0014061�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: d_mos3.model,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * mos model equations: spice level 3 equivalent */ h_headers { #include "d_mos123.h" } cc_headers { #include "l_denoise.h" } /*--------------------------------------------------------------------------*/ model BUILT_IN_MOS3 { level 3; public_keys { nmos3 polarity=pN; pmos3 polarity=pP; } dev_type BUILT_IN_MOS; inherit BUILT_IN_MOS123; independent { override { double mjsw "" default=.33; double tox "" default=1e-7; double cox "" final_default="P_EPS_OX/tox"; double vto "" final_default=0.0; double gamma "" final_default=0.0; double phi "" final_default=0.6; int mos_level "back-annotate for diode" name=DIODElevel print_test="mos_level != LEVEL" default=LEVEL; } raw_parameters { double kp "transconductance parameter" name=KP final_default=2e-5 print_test="!calc_kp" calc_print_test="calc_kp"; double nfs_cm "fast surface state density" name=NFS default=0.0; double vmax "max drift velocity of carriers" name=VMAx default=NA; double theta "mobility modulation" name=THEta default=0.0; double eta "static feedback" name=ETA default=0.0; double kappa "saturation field vector" name=KAPpa default=0.2; double delta "width effect on threshold voltage" name=DELta default=0.0; } calculated_parameters { double nfs "" calculate="nfs_cm*ICM2M2"; bool calc_kp "" default=false; double alpha "" calculate="((nsub != NA) ? (2. * P_EPS_SI) / (P_Q * nsub) : 0.)"; double xd "coeffDepLayWidth" calculate="sqrt(alpha)"; double cfsox "" calculate="P_Q * nfs / cox"; double delta3 "narrow factor" calculate="delta * M_PI_2 * P_EPS_SI / cox"; } code_pre { if (!has_good_value(tox)) { tox = 1e-7; } cox = P_EPS_OX / tox; if (kp == NA) { kp = uo * cox; calc_kp = true; } if (nsub != NA) { if (phi == NA) { phi = (2. * P_K_Q) * tnom_k * log(nsub/NI); if (phi < .1) { untested(); error(((!_sim->is_first_expand()) ? (bDEBUG) : (bWARNING)), long_label() + ": calculated phi too small, using .1\n"); phi = .1; } calc_phi = true; } if (gamma == NA) { gamma = sqrt(2. * P_EPS_SI * P_Q * nsub) / cox; calc_gamma = true; } if (vto == NA) { double phi_ms = (tpg == gtMETAL) ? polarity * (-.05 - (egap + polarity * phi) / 2.) : -(tpg * egap + phi) / 2.; double vfb = phi_ms - polarity * P_Q * nss / cox; vto = vfb + phi + gamma * sqrt(phi); calc_vto = true; } } } } temperature_dependent { calculated_parameters { double vt "" calculate="temp * P_K_Q"; double phi "" calculate="m->phi*tempratio + (-2*vt*(1.5*log(tempratio)+P_Q*(arg)))"; double sqrt_phi "" calculate="sqrt(phi)"; double beta "" calculate="(m->kp / tempratio4) * s->w_eff / s->l_eff"; double uo "" calculate="m->uo * tempratio4"; double vbi "" calculate="(fixzero( (m->vto - m->gamma * sqrt(m->phi) +.5*(m->egap-egap) + m->polarity* .5 * (phi-m->phi)), m->phi))"; } code_pre { double temp = d->_sim->_temp_c + P_CELSIUS0; double tempratio = temp / m->tnom_k; // ratio double tempratio4 = tempratio * sqrt(tempratio); double kt = temp * P_K; double egap = 1.16 - (7.02e-4*temp*temp) / (temp+1108.); double arg = (m->egap*tempratio - egap) / (2*kt); } } /*-----------------------------------------------------------------------*/ tr_eval { #define short_channel (m->xj != NOT_INPUT && m->xj > 0.) #define do_subthreshold (m->nfs != 0.) #define use_vmax (m->vmax != NOT_INPUT) /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ trace1(d->long_label().c_str(), d->evaliter()); trace3("", d->vds, d->vgs, d->vbs); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ d->reverse_if_needed(); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* square root term */ double sarg, v_phi_s, dsarg_dvbs; { if (d->vbs <= 0.) { v_phi_s = t->phi - d->vbs; sarg = sqrt(v_phi_s); dsarg_dvbs = -.5 / sarg; d->sbfwd = false; trace3("sb-ok", sarg, v_phi_s, dsarg_dvbs); }else{ untested(); sarg = t->sqrt_phi / (d->vbs / (2 * t->phi) + 1.); v_phi_s = sarg * sarg; dsarg_dvbs = -v_phi_s / (2 * t->phi*t->sqrt_phi); d->sbfwd = true; trace3("***sb-reversed***", sarg, v_phi_s, dsarg_dvbs); } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* short channel effect, body effect */ double fbody, dfbody_dvbs, qbonco, dqbdvb; { double fshort, dfs_dvbs; if (short_channel) { static const double D[3] = {.0631353, .8013292, -.01110777}; double wp = m->xd * sarg; double wp_xj = wp / m->xj; double wc_xj = D[0] + D[1] * wp_xj + D[2] * wp_xj * wp_xj; double ld_xj = m->ld / m->xj; double xj_le = m->xj / s->l_eff; double arga = wc_xj + ld_xj; double argc = wp_xj / (wp_xj + 1.); double argb = sqrt(1. - argc * argc); fshort = 1. - xj_le * (arga * argb - ld_xj); double dwp_dvbs = m->xd * dsarg_dvbs; double darga_dvbs = (D[1] + D[2] * (wp_xj + wp_xj)) * dwp_dvbs / m->xj; double dargb_dvbs = -argc * argc * (1. - argc) * dwp_dvbs / (argb*wp); dfs_dvbs = -xj_le * (darga_dvbs * argb + arga * dargb_dvbs); trace2("short-channel", fshort, dfs_dvbs); }else{ fshort = 1.; dfs_dvbs = 0.; trace2("not-short-channel", fshort, dfs_dvbs); } double gamma_fs = m->gamma * fshort; double fbodys = gamma_fs * .5 / (2 * sarg); double fnarrw = m->delta3 / s->w_eff; trace3("", gamma_fs, fbodys, fnarrw); fbody = fbodys + fnarrw; dfbody_dvbs = -fbodys * dsarg_dvbs / sarg + fbodys * dfs_dvbs / fshort; trace2("", fbody, dfbody_dvbs); qbonco = gamma_fs * sarg + fnarrw * v_phi_s; dqbdvb = gamma_fs * dsarg_dvbs + m->gamma * dfs_dvbs * sarg - fnarrw; trace2("", qbonco, dqbdvb); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* threshold voltage */ double vth, dvth_dvds, dvth_dvbs; { double sigma = m->eta * 8.15e-22 / (m->cox * s->l_eff*s->l_eff*s->l_eff); double vbix = t->vbi - sigma * d->vds; vth = vbix + qbonco; dvth_dvds = -(sigma); dvth_dvbs = dqbdvb; trace3("", vth, dvth_dvds, dvth_dvbs); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* joint weak inversion and strong inversion */ /* von */ double xn, vtxn, dxn_dvbs, dvon_dvds, dvon_dvbs; { if (do_subthreshold) { xn = 1. + m->cfsox + qbonco / (2 * v_phi_s); vtxn = t->vt * xn; dxn_dvbs = dqbdvb / (2*v_phi_s) - qbonco*dsarg_dvbs / (v_phi_s*sarg); trace3("do_sub", xn, vtxn, dxn_dvbs); d->von = vth + vtxn; dvon_dvds = dvth_dvds; dvon_dvbs = dvth_dvbs + t->vt * dxn_dvbs; d->vgst = d->vgs - d->von; trace4("", d->von, dvon_dvds, dvon_dvbs, d->vgst); d->subthreshold = (d->vgs < d->von); d->cutoff = false; }else{ xn = vtxn = dxn_dvbs = dvon_dvds = dvon_dvbs = 0.; d->von = vth; d->vgst = d->vgs - d->von; trace2("no_sub", vtxn, dxn_dvbs); trace4("", d->von, dvon_dvds, dvon_dvbs, d->vgst); d->subthreshold = false; d->cutoff = (d->vgs <= d->von); if (d->cutoff) { trace0("***** cut off *****"); d->vdsat = 0.; d->ids = 0.; d->gmf = d->gmr = 0.; d->gds = 0.; d->gmbf = d->gmbr = 0.; return; } } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* device is on */ /* mobility modulation by gate voltage */ double vc, onfg, us, dfg_dvgs, dfg_dvds, dfg_dvbs, beta; { double vgsx = (d->subthreshold) ? d->von : d->vgs; vc = vgsx - vth; onfg = m->theta * vc + 1.; double fgate = 1. / onfg; trace3("", vc, onfg, fgate); us = t->uo * fgate; beta = t->beta * fgate; trace4("", t->beta, beta, t->uo, us); dfg_dvgs = -(m->theta) * fgate * fgate; dfg_dvds = -dfg_dvgs * dvth_dvds; dfg_dvbs = -dfg_dvgs * dvth_dvbs; trace3("", dfg_dvgs, dfg_dvds, dfg_dvbs); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* saturation voltage */ /* vdsat, saturated */ double dvdsat_dvgs, dvdsat_dvds, dvdsat_dvbs; double onvdsc, vdsx; { double onfbdy = 1. / (fbody + 1.); double dvsdga = onfbdy; d->vdsat = vc * onfbdy; trace2("novm", d->vdsat, dvsdga); if (use_vmax) { double vdsc = s->l_eff * m->vmax / us; double argb = sqrt(d->vdsat * d->vdsat + vdsc * vdsc); d->vdsat += vdsc - argb; dvsdga *= (1. - d->vdsat / argb); trace2("vmax", d->vdsat, dvsdga); dvdsat_dvgs = dvsdga - (1. - vdsc / argb) * vdsc * dfg_dvgs * onfg; onvdsc = 1. / vdsc; }else{ dvdsat_dvgs = dvsdga; onvdsc = NOT_VALID; } d->saturated = (d->vds > d->vdsat); vdsx = (d->saturated) ? d->vdsat : d->vds; trace3("", d->vdsat, vdsx, onvdsc); dvdsat_dvds = -dvdsat_dvgs * dvth_dvds; dvdsat_dvbs = -dvdsat_dvgs * dvth_dvbs - d->vdsat * dfbody_dvbs * dvsdga; trace3("", dvdsat_dvgs, dvdsat_dvds, dvdsat_dvbs); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* short cut exit if vds == 0 */ if (vdsx == 0.) { /*900*/ trace2("***** vdsx == 0 *****", d->vdsat, d->vds); d->ids = 0.; d->gmf = d->gmr = 0.; d->gds = beta * vc; d->gmbf = d->gmbr = 0.; if (d->subthreshold) { d->gds *= exp(d->vgst / vtxn); } return; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* normalized drain current */ { double cdo = vc - (fbody + 1.) * .5 * vdsx; double dcodvb = -dvth_dvbs - dfbody_dvbs * .5 * vdsx; trace3("", t->beta, cdo, dcodvb); trace4("", vc, fbody, dvth_dvds, vdsx); d->gmf = vdsx; d->gds = vc - (fbody + 1. + dvth_dvds) * vdsx; d->gmbf = dcodvb * vdsx; d->ids = cdo * vdsx; trace4("1", d->ids, d->gmf, d->gds, d->gmbf); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* scale, but without velocity saturation effect */ { double cd1 = t->beta * d->ids; d->gmf *= beta; d->gmf += dfg_dvgs * cd1; d->gds *= beta; d->gds += dfg_dvds * cd1; d->gmbf *= beta; d->ids *= beta; trace4("2", d->ids, d->gmf, d->gds, d->gmbf); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* velocity saturation factor */ double fdrain, dfd_dvgs, dfd_dvds, dfd_dvbs; if (use_vmax) { assert(onvdsc != NOT_VALID); fdrain = 1. / (vdsx * onvdsc + 1.); double fd2 = fdrain * fdrain; double arga = fd2 * vdsx * onvdsc * onfg; dfd_dvgs = -dfg_dvgs * arga; dfd_dvds = -dfg_dvds * arga - fd2 * onvdsc; dfd_dvbs = -dfg_dvbs * arga; trace4("", fdrain, dfd_dvgs, dfd_dvds, dfd_dvbs); d->gmf *= fdrain; d->gmf += dfd_dvgs * d->ids; d->gds *= fdrain; d->gds += dfd_dvds * d->ids; d->gmbf *= fdrain; d->gmbf += dfd_dvbs * d->ids; d->ids *= fdrain; beta *= fdrain; trace4("3", d->ids, d->gmf, d->gds, d->gmbf); }else{ fdrain = 0.; /* used only if use_vmax */ dfd_dvgs = 0.; dfd_dvds = 0.; dfd_dvbs = 0.; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* channel length modulation */ double gds0; if (d->saturated) { double d_l, dl_dvd; double ddl_dvgs, ddl_dvds, ddl_dvbs; if (m->alpha == 0.) { d_l = dl_dvd = ddl_dvgs = ddl_dvds = ddl_dvbs = 0.; }else if (use_vmax) { /* use_vmax && m->alpha != 0 */ double gdsat = d->ids * (1. - fdrain) * onvdsc; gdsat = std::max(1e-12,gdsat); double gdoncd = gdsat / d->ids; double gdonfd = gdsat / (1. - fdrain); double gdonfg = gdsat * onfg; double dgdvg = gdoncd * d->gmf - gdonfd * dfd_dvgs + gdonfg * dfg_dvgs; double dgdvd = gdoncd * d->gds - gdonfd * dfd_dvds + gdonfg * dfg_dvds; double dgdvb = gdoncd *d->gmbf - gdonfd * dfd_dvbs + gdonfg * dfg_dvbs; double emax = d->ids / (s->l_eff * gdsat); double emax_o_ids = emax / d->ids; double emax_o_gdsat = emax / gdsat; double demax_dvgs = emax_o_ids * d->gmf - emax_o_gdsat * dgdvg; double demax_dvds = emax_o_ids * d->gds - emax_o_gdsat * dgdvd; double demax_dvbs = emax_o_ids * d->gmbf - emax_o_gdsat * dgdvb; double arga = emax * .5 * m->alpha; double argc = m->kappa * m->alpha; double argb = sqrt(arga * arga + argc * (d->vds - d->vdsat)); d_l = argb - arga; dl_dvd = argc / (argb + argb); double dl_demax = (arga / argb - 1.) * .5 * m->alpha; ddl_dvgs = dl_demax * demax_dvgs; ddl_dvds = dl_demax * demax_dvds - dl_dvd; ddl_dvbs = dl_demax * demax_dvbs; }else{ d_l = sqrt(m->kappa * (d->vds - d->vdsat) * m->alpha); dl_dvd = d_l * .5 / (d->vds - d->vdsat); ddl_dvgs = 0.; ddl_dvds = -dl_dvd; ddl_dvbs = 0.; } if (d_l > s->l_eff * .5) { /* punch through approximation */ d->punchthru = true; d_l = s->l_eff - s->l_eff*s->l_eff / (d_l*4.); double arga = (s->l_eff-d_l)*(s->l_eff-d_l) * 4./(s->l_eff*s->l_eff); ddl_dvgs *= arga; ddl_dvds *= arga; ddl_dvbs *= arga; dl_dvd *= arga; }else{ d->punchthru = false; } if (m->alpha != 0) { double lfact = 1. / (1. - d_l / s->l_eff); d->ids *= lfact; double diddl = d->ids / (s->l_eff - d_l); d->gmf = d->gmf * lfact + diddl * ddl_dvgs; gds0 = d->gds * lfact + diddl * ddl_dvds; d->gmbf = d->gmbf * lfact + diddl * ddl_dvbs; d->gmf += gds0 * dvdsat_dvgs; d->gmbf += gds0 * dvdsat_dvbs; d->gds = gds0 * dvdsat_dvds + diddl * dl_dvd; }else{ gds0 = 0; } trace2("", d_l, dl_dvd); trace3("", ddl_dvgs, ddl_dvds, ddl_dvbs); trace3("4", d->ids, gds0, d_l); }else{ d->punchthru = false; gds0 = 0; /* not saturated */ } trace4("4", d->ids, d->gmf, d->gds, d->gmbf); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* weak inversion -- subthreshold region */ if (d->subthreshold) { double wfact = exp(d->vgst / vtxn); d->ids *= wfact; double gms = d->gmf * wfact; double gmw = d->ids / vtxn; trace2("subth", gmw, gms); d->gmf = gmw; d->gmf += gds0 * dvdsat_dvgs * wfact; d->gds *= wfact; d->gds += (gms - gmw) * dvon_dvds; d->gmbf *= wfact; d->gmbf += (gms - gmw) * dvon_dvbs - gmw * d->vgst * dxn_dvbs / xn; trace4("5", d->ids, d->gmf, d->gds, d->gmbf); } if (d->reversed) { d->ids *= -1; d->gmr = d->gmf; d->gmbr = d->gmbf; d->gmf = d->gmbf = 0; }else{ d->gmr = d->gmbr = 0.; } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_mos4.model������������������������������������������������������������������������������������0000664�0000000�0000000�00000050646�11454012162�0014063�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: d_mos4.model,v 26.92 2008/08/23 05:40:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * MOS BSIM1 model. * derived from Spice3f4,Copyright 1990 Regents of the University of California * 1985 Hong J. Park, Thomas L. Quarles * Recoded for Gnucap model compiler, Al Davis, 2000 */ h_headers { #include "d_mos_base.h" } cc_headers { } /*--------------------------------------------------------------------------*/ model BUILT_IN_MOS4 { level 4; public_keys { nmos4 polarity=pN; pmos4 polarity=pP; } dev_type BUILT_IN_MOS; inherit BUILT_IN_MOS_BASE; independent { override { double mjsw "" final_default=.33; double pb "" final_default=0.1 quiet_min=0.1; double pbsw "" final_default=pb quiet_min=0.1; double cjo "" default=0.0; int cmodel "CMODEL" print_test="cmodel!=1" calculate="((!cmodel)?1:cmodel)"; int mos_level "back-annotate for diode" name=DIODElevel print_test="mos_level != LEVEL" default=LEVEL; } raw_parameters { double dl_u "Channel length reduction" name=DL default=0.; double dw_u "Channel width reduction" name=DW default=0.; double tox_u "Gate oxide thickness" name=TOX default=0. quiet_min=1e-20; double vdd "Supply voltage to specify mus" name=VDD default=0.; double wdf "Default width of source drain diffusion (ignored)" name=WDF default=0.; double dell "Length reduction of source drain diff (ignored)" name=DELL default=0.; double temp "temperature (ignored)" name=TEMP default=300.15; double xpart "Flag for channel charge partitioning" name=XPART default=0.; } calculated_parameters { double dl "" calculate="dl_u*MICRON2METER"; double dw "" calculate="dw_u*MICRON2METER"; double tox "" calculate="tox_u*MICRON2METER"; double cox "" calculate="3.453e-11 /*E_OX*/ / tox"; } } size_dependent { raw_parameters { double phi "Strong inversion surface potential" name=PHI default=0. positive quiet_min=.1; double vfb "Flat band voltage" name=VFB default=0.; double k1 "Bulk effect coefficient 1" name=K1 default=0. positive; double k2 "Bulk effect coefficient 2" name=K2 default=0. positive; double eta "VDS dependence of threshold voltage" name=ETA default=0.; double etaB "VBS dependence of eta (x2e)" name=X2E default=0.; double etaD "VDS dependence of eta (x3e)" name=X3E default=0.; double mobZero "Zero field mobility at VDS=0 VGS=VTH (muz)" name=MUZ default=0.; double mobZeroB "VBS dependence of muz (x2mz)" name=X2MZ default=0.; double mobVdd "Mobility @ VDS=VDD VGS=VTH, chan len modulation" name=MUS default=0.; double mobVddB "VBS dependence of mus (x2ms)" name=X2MS default=0.; double mobVddD "VDS dependence of mus (x3ms)" name=X3MS default=0.; double ugs "VGS dependence of mobility (u0)" name=U0 default=0.; double ugsB "VBS dependence of u0 (x2u0)" name=X2U0 default=0.; double uds "VDS dependence of mobility, velocity saturation" name=U1 default=0.; double udsB "VBS dependence of u1 (x2u1)" name=X2U1 default=0.; double udsD "VDS dependence of u1 (x3u1)" name=X3U1 default=0.; double n0 "Subthreshold slope (n0)" name=N0 default=0.; double nB "VBS dependence of subthreshold slope (nb)" name=NB default=0.; double nD "VDS dependence of subthreshold slope (nd)" name=ND default=0.; } calculated_parameters { double betaZero "Beta at vds = 0 and vgs = Vth" calculate="mobZero * CoxWoverL"; double betaZeroB "Vbs dependence of BetaZero" calculate="mobZeroB * CoxWoverL"; double betaVdd "Beta at vds=Vdd and vgs=Vth" calculate="mobVdd * CoxWoverL"; double betaVddB "Vbs dependence of BVdd" calculate="mobVddB * CoxWoverL"; double betaVddD "Vds dependence of BVdd" calculate="mobVddD * CoxWoverL"; double vt0 "" calculate="vfb + phi + k1 * sqrt(phi) - k2 * phi"; } code_pre { l_eff -= m->dl; w_eff -= m->dw; double L = l_eff/MICRON2METER; double W = w_eff/MICRON2METER; double CoxWoverL = 1e-4 * m->cox * w_eff / l_eff; } override { double cgate "" calculate="m->cox * w_eff * l_eff"; } } /*-----------------------------------------------------------------------*/ tr_eval { trace3("", d->vds, d->vgs, d->vbs); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ d->reverse_if_needed(); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ trace4("", c->lo, m->dl, c->wo, m->dw); trace3("", s->ugs, s->ugsB, d->vbs); double Ugs = s->ugs + s->ugsB * d->vbs; double dUgsdVbs; if(Ugs <= 0) { untested(); Ugs = 0; dUgsdVbs = 0.0; }else{ dUgsdVbs = s->ugsB; } trace2("", Ugs, dUgsdVbs); double Uds = s->uds + s->udsB * d->vbs + s->udsD * (d->vds - m->vdd); double dUdsdVbs; double dUdsdVds; if(Uds <= 0) { untested(); Uds = 0.0; dUdsdVbs = dUdsdVds = 0.0; }else{ double Leff = s->l_eff * 1e6; /* Leff in um */ Uds = Uds / Leff; dUdsdVbs = s->udsB / Leff; dUdsdVds = s->udsD / Leff; } trace3("", Uds, dUdsdVbs, dUdsdVds); double Vpb; if(d->vbs <= 0) { Vpb = s->phi - d->vbs; d->sbfwd = false; }else{ Vpb = s->phi; d->sbfwd = true; } double SqrtVpb = sqrt(Vpb); trace2("", Vpb, SqrtVpb); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* threshold voltage */ double dVthdVbs; double dVthdVds; { double Eta = s->eta + s->etaB * d->vbs + s->etaD * (d->vds - m->vdd); double dEtadVds; double dEtadVbs; if(Eta <= 0) { Eta = 0; dEtadVds = dEtadVbs = 0.0 ; }else if (Eta > 1) { untested(); Eta = 1; dEtadVds = dEtadVbs = 0; }else{ untested(); dEtadVds = s->etaD; dEtadVbs = s->etaB; } trace3("", Eta, dEtadVds, dEtadVbs); d->von = s->vfb + s->phi + s->k1 * SqrtVpb - s->k2 * Vpb - Eta * d->vds; dVthdVds = -Eta - dEtadVds * d->vds; dVthdVbs = s->k2 - 0.5 * s->k1 / SqrtVpb - dEtadVbs * d->vds; d->vgst = d->vgs - d->von; trace4("", d->von, dVthdVds, dVthdVbs, d->vgst); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ double G = 1. - 1./(1.744+0.8364 * Vpb); double A = 1. + 0.5*G*s->k1/SqrtVpb; A = std::max(A, 1.0); /* Modified */ double Arg = std::max((1 + Ugs * d->vgst), 1.0); double dGdVbs = -0.8364 * (1-G) * (1-G); double dAdVbs = 0.25 * s->k1 / SqrtVpb *(2*dGdVbs + G/Vpb); trace3("", G, A, Arg); trace2("", dGdVbs, dAdVbs); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* ids and derivatives calculation */ if (d->vgst < 0) { d->cutoff = true; /* cutoff */ d->ids = 0; d->gmf = 0; d->gds = 0; d->gmbf = 0; d->vdsat = 0; trace4("cutoff", d->ids, d->gmf, d->gds, d->gmbf); }else{ d->cutoff = false; /* Quadratic Interpolation for Beta0 (Beta at d->vgs = 0, vds=Vds) */ double Beta0; double dBeta0dVds; double dBeta0dVbs; { trace2("", m->tox, m->cox*1e-4); trace3("", s->betaVdd, s->betaVddB, d->vbs); double BetaVdd = (s->betaVdd + s->betaVddB * d->vbs); double dBetaVdd_dVds = std::max(s->betaVddD, 0.0); /* Modified */ trace2("", BetaVdd, dBetaVdd_dVds); if(d->vds > m->vdd) { Beta0 = BetaVdd + dBetaVdd_dVds * (d->vds - m->vdd); dBeta0dVds = dBetaVdd_dVds; dBeta0dVbs = s->betaVddB; trace3("vds>vdd", Beta0, dBeta0dVds, dBeta0dVbs); }else{ double Beta_Vds_0 = (s->betaZero + s->betaZeroB * d->vbs); double VddSquare = m->vdd * m->vdd; double C1 = (-BetaVdd + Beta_Vds_0+dBetaVdd_dVds*m->vdd) / VddSquare; double C2 = 2 * (BetaVdd - Beta_Vds_0) / m->vdd - dBetaVdd_dVds; trace4("", Beta_Vds_0, VddSquare, C1, C2); double dBeta_Vds_0_dVbs = s->betaZeroB; double dBetaVdd_dVbs = s->betaVddB; double dC1dVbs = (dBeta_Vds_0_dVbs - dBetaVdd_dVbs) / VddSquare; double dC2dVbs = dC1dVbs * (-2) * m->vdd; trace4("", dBeta_Vds_0_dVbs, dBetaVdd_dVbs, dC1dVbs, dC2dVbs); Beta0 = (C1 * d->vds + C2) * d->vds + Beta_Vds_0; dBeta0dVds = 2*C1*d->vds + C2; dBeta0dVbs = dC1dVbs * d->vds * d->vds + dC2dVbs * d->vds + dBeta_Vds_0_dVbs; trace3("vdsvgst );*/ double Beta = Beta0 / Arg ; double dBetadVgs = -Beta * Ugs / Arg; double dBetadVds = dBeta0dVds / Arg - dBetadVgs * dVthdVds ; double dBetadVbs = dBeta0dVbs / Arg + Beta * Ugs * dVthdVbs / Arg - Beta * d->vgst * dUgsdVbs / Arg; trace4("", Beta, dBetadVgs, dBetadVds, dBetadVbs); /*d->vdsat = std::max(d->vgst / ( A + Uds * d->vgst ), 0.0);*/ double Vc = Uds * d->vgst / A; if(Vc < 0.0) { untested(); Vc=0.0; } double Term1 = sqrt(1 + 2 * Vc); double K = 0.5 * (1 + Vc + Term1); d->vdsat = std::max(d->vgst / (A * sqrt(K)) , 0.0); trace4("", Vc, Term1, K, d->vdsat); if(d->vds < d->vdsat) { /* Triode Region */ d->saturated = false; /*Argl1 = 1 + Uds * d->vds;*/ double Argl1 = std::max((1 + Uds * d->vds), 1.); double Argl2 = d->vgst - 0.5 * A * d->vds; trace2("", Argl1, Argl2); d->ids = Beta * Argl2 * d->vds / Argl1; d->gmf = (dBetadVgs * Argl2 * d->vds + Beta * d->vds) / Argl1; d->gds = (dBetadVds * Argl2 * d->vds + Beta * (d->vgst - d->vds * dVthdVds - A * d->vds) - d->ids * (d->vds * dUdsdVds + Uds)) / Argl1; d->gmbf = (dBetadVbs * Argl2 * d->vds + Beta * d->vds * (-dVthdVbs - 0.5 * d->vds * dAdVbs) - d->ids * d->vds * dUdsdVbs) / Argl1; trace4("triode", d->ids, d->gmf, d->gds, d->gmbf); }else{ /* Pinchoff (Saturation) Region */ d->saturated = true; double Args1 = 1. + 1. / Term1; double dVcdVgs = Uds / A; double dVcdVds = d->vgst * dUdsdVds / A - dVcdVgs * dVthdVds; double dVcdVbs = (d->vgst * dUdsdVbs - Uds * (dVthdVbs + d->vgst * dAdVbs / A )) / A; double dKdVc = 0.5 * Args1; double dKdVgs = dKdVc * dVcdVgs; double dKdVds = dKdVc * dVcdVds; double dKdVbs = dKdVc * dVcdVbs; double Args2 = d->vgst / A / K; double Args3 = Args2 * d->vgst; trace3("", Args1, Args2, Args3); trace3("", dVcdVgs, dVcdVds, dVcdVbs); trace4("", dKdVc, dKdVgs, dKdVds, dKdVbs); d->ids = 0.5 * Beta * Args3; d->gmf = 0.5 * Args3 * dBetadVgs + Beta * Args2 - d->ids * dKdVgs / K; d->gds = 0.5*Args3*dBetadVds - Beta*Args2*dVthdVds - d->ids*dKdVds/K; d->gmbf = 0.5 * dBetadVbs * Args3 - Beta * Args2 *dVthdVbs - d->ids * (dAdVbs / A + dKdVbs / K); trace4("sat", d->ids, d->gmf, d->gds, d->gmbf); } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* SubthresholdComputation */ /* The following 'if' statement has been modified so that subthreshold * * current computation is always executed unless N0 >= 200. This should * * get rid of the Ids kink seen on Ids-Vgs plots at low Vds. * * Peter M. Lee * * 6/8/90 * * Old 'if' statement: (reversed) * * if( (N0 >= 200) || (d->vgst < Vcut ) || (d->vgst > (-0.5*Vcut))) */ //double Vcut = - 40. * s->n0 * t->vt ; if (s->n0 < 200) { double N = s->n0 + s->nB*d->vbs + s->nD*d->vds; /* subthreshold slope */ trace4("", s->n0, s->nB, s->nD, N); if (N < 0.5) { untested(); N = 0.5; } const double ref_temp = 300.15; // ignore real temp for spice compatibility const double vt0 = ref_temp * P_K_Q; const double Vtsquare = vt0 * vt0 ; const double nvt0 = N * vt0; double Warg1 = exp(-d->vds / vt0); double Wds = 1 - Warg1; double Wgs = exp( d->vgst / nvt0); double Warg2 = 6.04965 * Vtsquare * s->betaZero; double Ilimit = 4.5 * Vtsquare * s->betaZero; double Iexp = Warg2 * Wgs * Wds; d->ids += Ilimit * Iexp / (Ilimit + Iexp); double Temp1 = Ilimit / (Ilimit + Iexp); Temp1 = Temp1 * Temp1; double Temp3 = Ilimit / (Ilimit + Wgs * Warg2); Temp3 = Temp3 * Temp3 * Warg2 * Wgs; /* if ( Temp3 > Ilimit ) Temp3=Ilimit;*/ d->gmf += Temp1 * Iexp / nvt0; /* gds term has been modified to prevent blow up at Vds=0 */ d->gds += Temp3 * (Wds / nvt0 * (dVthdVds + d->vgst * s->nD / N) + Warg1 / vt0); d->gmbf -= Temp1 * Iexp * (dVthdVbs + d->vgst * s->nB / N) / nvt0; trace3("", vt0, Vtsquare, nvt0); trace4("", Warg1, Wds, Wgs, Warg2); trace4("", Ilimit, Iexp, Temp1, Temp3); trace4("sub", d->ids, d->gmf, d->gds, d->gmbf); }else{ untested(); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Some Limiting of DC Parameters */ if(d->ids < 0.0) d->ids = 0.0; if(d->gmf < 0.0) d->gmf = 0.0; if(d->gds < 0.0) d->gds = 0.0; if(d->gmbf < 0.0) d->gmbf = 0.0; trace4("final", d->ids, d->gmf, d->gds, d->gmbf); trace3("", G, A, s->phi); trace1("", m->xpart); double Vth0 = s->vfb + s->phi + s->k1 * SqrtVpb; // almost same as d->von double Vgs_Vth = d->vgs - Vth0; // almost same as d->vgst trace2("", Vth0, Vgs_Vth); double Arg1 = A * d->vds; double Arg2 = Vgs_Vth - 0.5 * Arg1; double Arg3 = d->vds - Arg1; trace3("", Arg1, Arg2, Arg3); /*double*/ dVthdVbs = -0.5 * s->k1 / SqrtVpb; /*dbl*/ dAdVbs = 0.5 * s->k1 * (0.5*G/Vpb - 0.8364*(1-G)*(1-G)) / SqrtVpb; trace2("", dVthdVbs, dAdVbs); double Ent = std::max(Arg2,1.0e-8); double dEntdVds = -0.5 * A; double dEntdVbs = -dVthdVbs - 0.5 * d->vds * dAdVbs; trace3("", Ent, dEntdVds, dEntdVbs); double VdsPinchoff = std::max(Vgs_Vth / A, 0.0); double Vgb = d->vgs - d->vbs ; double Vgb_Vfb = Vgb - s->vfb; trace3("", VdsPinchoff, Vgb, Vgb_Vfb); if(Vgb_Vfb < 0) { /* Accumulation Region */ untested(); d->qgate = s->cgate * Vgb_Vfb; d->qbulk = -d->qgate; d->qdrn = 0. ; d->cggb = s->cgate; d->cgdb = 0.; d->cgsb = 0.; d->cbgb = -s->cgate; d->cbdb = 0.; d->cbsb = 0.; d->cdgb = 0.; d->cddb = 0.; d->cdsb = 0.; trace4("", d->qgate, d->cggb, d->cgdb, d->cgsb); trace4("", d->qbulk, d->cbgb, d->cbdb, d->cbsb); trace4("acc", d->qdrn, d->cdgb, d->cddb, d->cdsb); }else if (d->vgs < Vth0) { /* Subthreshold Region */ d->qgate = 0.5*s->cgate*s->k1*s->k1*(-1+sqrt(1+4*Vgb_Vfb/(s->k1*s->k1))); d->cggb = s->cgate / sqrt(1 + 4 * Vgb_Vfb / (s->k1 * s->k1)); d->cgdb = d->cgsb = 0.; d->qbulk = -d->qgate; d->cbgb = -d->cggb; d->cbdb = d->cbsb = 0.0; d->qdrn = 0.; d->cdgb = d->cddb = d->cdsb = 0.0; trace4("", d->qgate, d->cggb, d->cgdb, d->cgsb); trace4("", d->qbulk, d->cbgb, d->cbdb, d->cbsb); trace4("sub", d->qdrn, d->cdgb, d->cddb, d->cdsb); }else if (d->vds < VdsPinchoff) { /* triode region */ double EntSquare = Ent * Ent; trace1("tri", EntSquare); double Argl1 = 1.2e1 * EntSquare; double Argl2 = 1.0 - A; double Argl3 = Arg1 * d->vds; trace3("", Argl1, Argl2, Argl3); double Argl5; if (Ent > 1.0e-8) { Argl5 = Arg1 / Ent; }else{ untested(); Argl5 = 2.0; } double Argl7 = Argl5 / 1.2e1; double Argl8 = 6.0 * Ent; trace3("", Argl5, Argl7, Argl8); d->qgate = s->cgate * (d->vgs - s->vfb - s->phi - 0.5 * d->vds + d->vds * Argl7); d->cggb = s->cgate * (1.0 - Argl3 / Argl1); d->cgdb = s->cgate * (-0.5 + Arg1 / Argl8 - Argl3 * dEntdVds / Argl1); double cgbb = s->cgate * (d->vds*d->vds*dAdVbs*Ent-Argl3*dEntdVbs)/Argl1; d->cgsb = -(d->cggb + d->cgdb + cgbb); trace4("", d->qgate, d->cggb, d->cgdb, d->cgsb); d->qbulk = s->cgate * (-Vth0 + s->vfb + s->phi + 0.5*Arg3 - Arg3*Argl7); d->cbgb = s->cgate * Argl3 * Argl2 / Argl1; d->cbdb = s->cgate * Argl2 * (0.5 - Arg1/Argl8 + Argl3 * dEntdVds/Argl1); double cbbb = -s->cgate * (dVthdVbs + 0.5 * d->vds * dAdVbs +d->vds*d->vds*((1.0-2.0*A)*dAdVbs*Ent-Argl2*A*dEntdVbs)/Argl1); d->cbsb = -(d->cbgb + d->cbdb + cbbb); trace4("", d->qbulk, d->cbgb, d->cbdb, d->cbsb); if (m->xpart >= 1) { /*0/100 partitioning for drain/source chArges at saturation region*/ double Argl9 = 0.125 * Argl5 * Argl5; //t d->qdrn = -s->cgate * (0.5*Vgs_Vth - 0.75*Arg1 + 0.125*Arg1*Argl5); d->cdgb = -s->cgate * (0.5 - Argl9); d->cddb = s->cgate * (0.75*A - 0.25*A*Arg1/Ent + Argl9*dEntdVds); double cdbb = s->cgate * (0.5 * dVthdVbs + d->vds * dAdVbs * (0.75 - 0.25 * Argl5 ) + Argl9 * dEntdVbs); d->cdsb = -(d->cdgb + d->cddb + cdbb); trace2("", Argl9, cdbb); trace4("tri 0/100", d->qdrn, d->cdgb, d->cddb, d->cdsb); }else{ /*40/60 partitioning for drain/source chArges at saturation region*/ double Vgs_VthSquare = Vgs_Vth*Vgs_Vth; trace2("", Vgs_Vth, Vgs_VthSquare); double Arg5 = Arg1*Arg1; double Vcom = Vgs_Vth*Vgs_Vth/6.0-1.25e-1*Arg1*Vgs_Vth+2.5e-2*Arg5; double Argl4 = Vcom/Ent/EntSquare; double Argl6; if (Ent > 1.0e-8) { Argl6 = Vcom / EntSquare; }else{ untested(); Argl6 = 4.0 / 1.5e1; } d->qdrn = -s->cgate * (0.5 * (Vgs_Vth-Arg1) + Arg1 * Argl6); d->cdgb = -s->cgate * (0.5 + Arg1*(4.0*Vgs_Vth-1.5*Arg1)/Argl1 - 2.0*Arg1*Argl4); d->cddb = s->cgate*(0.5*A+2.0*Arg1*dEntdVds*Argl4-A*(2.0*Vgs_VthSquare -3.0*Arg1*Vgs_Vth+0.9*Arg5)/Argl1); double cdbb =s->cgate*(0.5*dVthdVbs+0.5*d->vds*dAdVbs+2.0*Arg1*dEntdVbs *Argl4-d->vds*(2.0*Vgs_VthSquare*dAdVbs-4.0*A*Vgs_Vth*dVthdVbs-3.0 *Arg1*Vgs_Vth*dAdVbs+1.5*A*Arg1*dVthdVbs+0.9*Arg5*dAdVbs) /Argl1); d->cdsb = -(d->cdgb + d->cddb + cdbb); trace4("", Vcom, Argl4, Argl6, cdbb); trace4("lin 40/60", d->qdrn, d->cdgb, d->cddb, d->cdsb); } }else{ /* saturation region */ assert(d->vds >= VdsPinchoff); double Args1 = 1.0 / (3.0 * A); trace2("sat", s->cgate, Args1); d->qgate = s->cgate * (d->vgs - s->vfb - s->phi - Vgs_Vth * Args1); d->cggb = s->cgate * (1.0 - Args1); d->cgdb = 0.0; double cgbb = s->cgate * Args1 * (dVthdVbs + Vgs_Vth * dAdVbs / A); d->cgsb = -(d->cggb + d->cgdb + cgbb); trace4("", d->qgate, d->cggb, d->cgdb, d->cgsb); d->qbulk = s->cgate * (s->vfb + s->phi - Vth0 + (1.0-A)*Vgs_Vth*Args1); d->cbgb = s->cgate * (Args1 - 1.0 / 3.0); d->cbdb = 0.0; double cbbb = -s->cgate * ((2.0 / 3.0 + Args1) * dVthdVbs + Vgs_Vth * Args1 * dAdVbs / A); d->cbsb = -(d->cbgb + d->cbdb + cbbb); trace4("", d->qbulk, d->cbgb, d->cbdb, d->cbsb); if (m->xpart >= 1) { /*0/100 partitioning for drain/source chArges at saturation region*/ d->qdrn = 0.0; d->cdgb = 0.0; d->cddb = 0.0; d->cdsb = 0.0; trace4("sat 0/100", d->qdrn, d->cdgb, d->cddb, d->cdsb); }else{ /*40/60 partitioning for drain/source chArges at saturation region*/ const double co4v15 = 4./15.; d->qdrn = -co4v15 * s->cgate * Vgs_Vth; d->cdgb = -co4v15 * s->cgate; d->cddb = 0.0; double cdbb = co4v15 * s->cgate * dVthdVbs; d->cdsb = -(d->cdgb + d->cddb + cdbb); trace4("sat 40/60", d->qdrn, d->cdgb, d->cddb, d->cdsb); } } if (d->reversed) { d->ids *= -1; d->gmr = d->gmf; d->gmbr = d->gmbf; d->gmf = d->gmbf = 0; }else{ d->gmr = d->gmbr = 0.; } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ������������������������������������������������������������������������������������������src/d_mos5.model������������������������������������������������������������������������������������0000664�0000000�0000000�00000065407�11454012162�0014065�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: d_mos5.model,v 26.92 2008/08/23 05:40:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Spice BSIM2 model * derived from Spice3f4,Copyright 1990 Regents of the University of California * 1988 Min-Chie Jeng, Hong J. Park, Thomas L. Quarles * Recoded for Gnucap model compiler, Al Davis, 2000 */ h_headers { #include "d_mos_base.h" } cc_headers { } /*--------------------------------------------------------------------------*/ model BUILT_IN_MOS5 { level 5; public_keys { nmos5 polarity=pN; pmos5 polarity=pP; } dev_type BUILT_IN_MOS; inherit BUILT_IN_MOS_BASE; independent { override { double mjsw "" final_default=.33; double pb "" final_default=0.1 quiet_min=0.1; double pbsw "" final_default=pb quiet_min=0.1; double cjo "" default=0.0; int cmodel "CMODEL" print_test="cmodel!=1" calculate="((!cmodel)?1:cmodel)"; int mos_level "back-annotate for diode" name=DIODElevel print_test="mos_level != LEVEL" default=LEVEL; } raw_parameters { double dl_u "Channel length reduction" name=DL default=0.; double dw_u "Channel width reduction" name=DW default=0.; double tox_u "Gate oxide thickness" name=TOX default=0. quiet_min=1e-20; double vdd "Max Vds" name=VDD default=0.; double vgg "Max Vgs" name=VGG default=0.; double vbb "Max Vbs" name=VBB default=0.; double wdf "Default width of source drain diffusion (ignored)" name=WDF default=0.; double dell "Length reduction of source drain diff (ignored)" name=DELL default=0.; double temp_c "temperature" name=TEMP default=27.; double xpart "Flag for channel charge partitioning" name=XPART default=0.; } calculated_parameters { double dl "" calculate="dl_u*MICRON2METER"; double dw "" calculate="dw_u*MICRON2METER"; double tox "" calculate="tox_u*MICRON2METER"; double cox "" calculate="3.453e-11 /*E_OX*/ / tox"; double vdd2 "" calculate="2 * vdd"; double vgg2 "" calculate="2 * vgg"; double vbb2 "" calculate="2 * vbb"; double Vtm "" calculate="8.625e-5 /*K/Q*/ * (temp_c + P_CELSIUS0 -.15)"; } } size_dependent { raw_parameters { double phi "Strong inversion surface potential" name=PHI default=0.; double vfb "flat band voltage at given L and W" name=VFB default=0.; double k1 "bulk effect coefficient 1" name=K1 default=0.; double k2 "bulk effect coefficient 2" name=K2 default=0.; double eta0 "drain induced barrier lowering" name=ETA0 default=0.; double etaB "Vbs dependence of Eta" name=ETAB default=0.; double mob0 "" name=MU0 default=0.; double mob0B "" name=MU0B default=0.; double mobs0 "" name=MUS0 default=0.; double mobsB "" name=MUSB default=0.; double mob20 "" name=MU20 default=0.; double mob2B "" name=MU2B default=0.; double mob2G "" name=MU2G default=0.; double mob30 "" name=MU30 default=0.; double mob3B "" name=MU3B default=0.; double mob3G "" name=MU3G default=0.; double mob40 "" name=MU40 default=0.; double mob4B "" name=MU4B default=0.; double mob4G "" name=MU4G default=0.; double ua0 "Linear Vgs dependence of Mobility" name=UA0 default=0.; double uaB "Vbs dependence of Ua" name=UAB default=0.; double ub0 "Quadratic Vgs dependence of Mobility" name=UB0 default=0.; double ubB "Vbs dependence of Ub" name=UBB default=0.; double u10 "Drift Velocity Saturation due to Vds" name=U10 default=0.; double u1B "Vbs dependence of U1" name=U1B default=0.; double u1D "Vds dependence of U1" name=U1D default=0.; double n0 "Subthreshold slope at Vds=0, Vbs=0" name=N0 default=0. positive; double nB "Vbs dependence of n" name=NB default=0.; double nD "Vds dependence of n" name=ND default=0.; double vof0 "Vth offset at Vds=0, Vbs=0" name=VOF0 default=0.; double vofB "Vbs dependence of Vof" name=VOFB default=0.; double vofD "Vds dependence of Vof" name=VOFD default=0.; double ai0 "Pre-factor in hot-electron effects" name=AI0 default=0.; double aiB "Vbs dependence of Ai" name=AIB default=0.; double bi0 "Exp-factor in hot-electron effects" name=BI0 default=0.; double biB "Vbs dependence of Bi" name=BIB default=0.; double vghigh "Upper bound of cubic spline function" name=VGHIGH default=0.; double vglow "Lower bound of cubic spline function" name=VGLOW default=0.; } calculated_parameters { double beta0 "Beta at Vds = 0 and Vgs = Vth" calculate="mob0 * CoxWoverL"; double beta0B "Vbs dependence of Beta0" calculate="mob0B * CoxWoverL"; double betas0 "Beta at Vds=Vdd and Vgs=Vth" calculate="mobs0 * CoxWoverL" quiet_min="1.01*beta0"; double betasB "Vbs dependence of Betas" calculate="mobsB * CoxWoverL"; double beta20 "Vds dependence of Beta in tanh term" calculate="mob20"; double beta2B "Vbs dependence of Beta2" calculate="mob2B"; double beta2G "Vgs dependence of Beta2" calculate="mob2G"; double beta30 "Vds dependence of Beta in linear term" calculate="mob30 * CoxWoverL"; double beta3B "Vbs dependence of Beta3" calculate="mob3B * CoxWoverL"; double beta3G "Vgs dependence of Beta3" calculate="mob3G * CoxWoverL"; double beta40 "Vds dependence of Beta in quadra term" calculate="mob40 * CoxWoverL"; double beta4B "Vbs dependence of Beta4" calculate="mob4B * CoxWoverL"; double beta4G "Vgs dependence of Beta4" calculate="mob4G * CoxWoverL"; double Phis3 "" calculate="sqrt(phi) * phi"; double One_Third_CoxWL "" calculate="cgate / 3.0"; double Two_Third_CoxWL "" calculate="2.0 * One_Third_CoxWL"; double Arg; } code_pre { l_eff -= m->dl; w_eff -= m->dw; cgate = m->cox * w_eff * l_eff; double L = l_eff/MICRON2METER; double W = w_eff/MICRON2METER; double CoxWoverL = 1e-4 * m->cox * w_eff / l_eff; } override { double cgate "" calculate="m->cox * w_eff * l_eff"; } code_post { double tmp = betas0 - beta0 - beta0B * m->vbb; if ((-betasB * m->vbb) > tmp) { untested(); betasB = -tmp / m->vbb; } Arg = betasB - beta0B - m->vdd * (beta3B - m->vdd * beta4B); } } /*-----------------------------------------------------------------------*/ tr_eval { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ trace3("", d->vds, d->vgs, d->vbs); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ d->reverse_if_needed(); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ trace4("", c->lo, m->dl, c->wo, m->dw); double Vbs = std::max(m->vbb2, d->vbs); double Vgs = std::min(m->vgg2, d->vgs); double Vds = std::min(m->vdd2, d->vds); trace3("", Vbs, Vgs, Vds); /* Threshold Voltage. */ double Phisb, dPhisb_dVb, T1s, dT1s_dVb; if (Vbs <= 0.0) { d->sbfwd = false; Phisb = s->phi - Vbs; dPhisb_dVb = -1.0; T1s = sqrt(Phisb); dT1s_dVb = -0.5 / T1s; trace4("-", Phisb, dPhisb_dVb, T1s, dT1s_dVb); }else{ d->sbfwd = true; double tmp = s->phi / (s->phi + Vbs); Phisb = s->phi * tmp; dPhisb_dVb = -tmp * tmp; T1s = s->Phis3 / (s->phi + 0.5 * Vbs); dT1s_dVb = -0.5 * T1s * T1s / s->Phis3; trace4("+", Phisb, dPhisb_dVb, T1s, dT1s_dVb); } double Eta = s->eta0 + s->etaB * Vbs; double Ua = s->ua0 + s->uaB * Vbs; double Ub = s->ub0 + s->ubB * Vbs; double U1s = s->u10 + s->u1B * Vbs; trace4("", Eta, Ua, Ub, U1s); d->von = s->vfb + s->phi + s->k1*T1s - s->k2*Phisb - Eta*Vds; double dVth_dVd = -Eta; double dVth_dVb = s->k1 * dT1s_dVb + s->k2 - s->etaB * Vds; d->vgst = Vgs - d->von; trace4("", d->von, dVth_dVd, dVth_dVb, d->vgst); double Aa, dAa_dVb, Inv_Aa; { double tmp = 1.0 / (1.744 + 0.8364 * Phisb); double Gg = 1.0 - tmp; double dGg_dVb = 0.8364 * tmp * tmp * dPhisb_dVb; double T0 = Gg / T1s; trace4("", tmp, Gg, dGg_dVb, T0); double tmp1 = 0.5 * T0 * s->k1; Aa = 1.0 + tmp1; dAa_dVb = (Aa - 1.0) * (dGg_dVb / Gg - dT1s_dVb / T1s); Inv_Aa = 1.0 / Aa; trace4("", tmp1, Aa, dAa_dVb, Inv_Aa); } trace3("", s->vghigh, s->vglow, d->vgst); double Exp0, Exp1, n, Vgeff, dVgeff_dVg, dVgeff_dVd, dVgeff_dVb; if ((d->vgst >= s->vghigh) || (s->n0 == 0.0)) { Exp0 = NOT_VALID; Exp1 = NOT_VALID; n = NOT_VALID; Vgeff = d->vgst; dVgeff_dVg = 1.0; dVgeff_dVd = -dVth_dVd; dVgeff_dVb = -dVth_dVb; trace0("vgst>vghigh"); }else{ double Vof = s->vof0 + s->vofB * Vbs + s->vofD * Vds; n = s->n0 + s->nB / T1s + s->nD * Vds; double tmp = 0.5 / (n * m->Vtm); trace3("", Vof, n, tmp); double ExpArg1 = -Vds / m->Vtm; ExpArg1 = std::max(ExpArg1, -30.0); Exp1 = exp(ExpArg1); double tmp1 = 1.0 - Exp1; tmp1 = std::max(tmp1, 1.0e-18); double tmp2 = 2.0 * Aa * tmp1; trace4("", ExpArg1, Exp1, tmp1, tmp2); // exports Exp0, Vgeff, dVgeff_dVg, dVgeff_dVd, dVgeff_dVb if (d->vgst <= s->vglow) { double ExpArg = d->vgst * tmp; ExpArg = std::max(ExpArg, -30.0); Exp0 = exp(0.5 * Vof + ExpArg); Vgeff = sqrt(tmp2) * m->Vtm * Exp0; double T0 = n * m->Vtm; dVgeff_dVg = Vgeff * tmp; dVgeff_dVd = dVgeff_dVg * (n / tmp1 * Exp1 - dVth_dVd - d->vgst * s->nD / n + T0 * s->vofD); dVgeff_dVb = dVgeff_dVg * (s->vofB * T0 - dVth_dVb + s->nB * d->vgst / (n * T1s * T1s) * dT1s_dVb + T0 * Inv_Aa * dAa_dVb); trace0("vgstvglow * tmp; ExpArg = std::max(ExpArg, -30.0); Exp0 = exp(0.5 * Vof + ExpArg); Vgeff = sqrt(2.0 * Aa * (1.0 - Exp1)) * m->Vtm * Exp0; double Con1 = s->vghigh; double Con3 = Vgeff; double Con4 = Con3 * tmp; double SqrVghigh = s->vghigh * s->vghigh; double SqrVglow = s->vglow * s->vglow; double CubVghigh = s->vghigh * SqrVghigh; double CubVglow = s->vglow * SqrVglow; double T0 = 2.0 * s->vghigh; double T1 = 2.0 * s->vglow; double T2 = 3.0 * SqrVghigh; double T3 = 3.0 * SqrVglow; double T4 = s->vghigh - s->vglow; double T5 = SqrVghigh - SqrVglow; double T6 = CubVghigh - CubVglow; double T7 = Con1 - Con3; double delta = (T1-T0) * T6 + (T2-T3) * T5 + (T0*T3 - T1*T2) * T4; delta = 1.0 / delta; double Coeffb = (T1 - Con4 * T0) * T6 + (Con4 * T2 - T3) * T5 + (T0 * T3 - T1 * T2) * T7; double Coeffc = (Con4-1.0) * T6 + (T2-T3) * T7 + (T3 - Con4*T2) * T4; double Coeffd = (T1-T0) * T7 + (1.0-Con4) * T5 + (Con4*T0 - T1) * T4; double Coeffa = SqrVghigh * (Coeffc + Coeffd * T0); Vgeff = (Coeffa + d->vgst * (Coeffb + d->vgst*(Coeffc+d->vgst*Coeffd))) *delta; dVgeff_dVg = (Coeffb + d->vgst*(2.0*Coeffc+3.0*d->vgst*Coeffd)) *delta; T7 = Con3 * tmp; double T8 = dT1s_dVb * s->nB / (T1s * T1s * n); double T9 = n * m->Vtm; double dCon3_dVd = T7*(n*Exp1/tmp1 -s->vglow*s->nD/n + T9*s->vofD); double dCon3_dVb = T7*(T9*Inv_Aa*dAa_dVb + s->vglow*T8 + T9*s->vofB); double dCon4_dVd = tmp * dCon3_dVd - T7 * s->nD / n; double dCon4_dVb = tmp * dCon3_dVb + T7 * T8; double dCoeffb_dVd = dCon4_dVd*(T2*T5-T0*T6) + dCon3_dVd*(T1*T2-T0*T3); double dCoeffc_dVd = dCon4_dVd * (T6 - T2*T4) + dCon3_dVd * (T3 - T2); double dCoeffd_dVd = dCon4_dVd * (T0*T4 - T5) + dCon3_dVd * (T0 - T1); double dCoeffa_dVd = SqrVghigh * (dCoeffc_dVd + dCoeffd_dVd * T0); dVgeff_dVd = -dVgeff_dVg * dVth_dVd + (dCoeffa_dVd + d->vgst * (dCoeffb_dVd + d->vgst * (dCoeffc_dVd + d->vgst * dCoeffd_dVd))) * delta; double dCoeffb_dVb = dCon4_dVb*(T2*T5-T0*T6) + dCon3_dVb*(T1*T2-T0*T3); double dCoeffc_dVb = dCon4_dVb * (T6 - T2*T4) + dCon3_dVb * (T3 - T2); double dCoeffd_dVb = dCon4_dVb * (T0*T4 - T5) + dCon3_dVb * (T0 - T1); double dCoeffa_dVb = SqrVghigh * (dCoeffc_dVb + dCoeffd_dVb * T0); dVgeff_dVb = -dVgeff_dVg * dVth_dVb + (dCoeffa_dVb + d->vgst * (dCoeffb_dVb + d->vgst * (dCoeffc_dVb + d->vgst * dCoeffd_dVb))) * delta; trace0("else"); } } trace3("", Exp0, Exp1, n); trace4("", Vgeff, dVgeff_dVg, dVgeff_dVd, dVgeff_dVb); double dVdsat_dVd, dVdsat_dVg, dVdsat_dVb; if (Vgeff > 0.0) { // normal operation d->cutoff = false; double Uvert = 1.0 + Vgeff * (Ua + Vgeff * Ub); Uvert = std::max(Uvert, 0.2); double Inv_Uvert = 1.0 / Uvert; double dUvert_dVg, dUvert_dVd, dUvert_dVb; { double T8 = Ua + 2.0 * Ub * Vgeff; dUvert_dVg = T8 * dVgeff_dVg; dUvert_dVd = T8 * dVgeff_dVd; dUvert_dVb = T8 * dVgeff_dVb + Vgeff * (s->uaB + Vgeff * s->ubB); trace2("", T8, Uvert); trace3("", dUvert_dVg, dUvert_dVd, dUvert_dVb); } double Vc, dVc_dVg, dVc_dVd, dVc_dVb; { double T8 = U1s * Inv_Aa * Inv_Uvert; Vc = T8 * Vgeff; double T9 = Vc * Inv_Uvert; dVc_dVg = T8 * dVgeff_dVg - T9 * dUvert_dVg; dVc_dVd = T8 * dVgeff_dVd - T9 * dUvert_dVd; dVc_dVb = T8 * dVgeff_dVb + s->u1B * Vgeff * Inv_Aa * Inv_Uvert - Vc * Inv_Aa * dAa_dVb - T9 * dUvert_dVb; trace3("", T8, T9, Vc); trace3("", dVc_dVg, dVc_dVd, dVc_dVb); } double Kk, dKk_dVc; { double tmp2 = sqrt(1.0 + 2.0 * Vc); Kk = 0.5 * (1.0 + Vc + tmp2); dKk_dVc = 0.5 + 0.5 / tmp2; trace3("", tmp2, Kk, dKk_dVc); } { double T8 = Inv_Aa / sqrt(Kk); d->vdsat = std::max(Vgeff * T8, 1.0e-18); double T9 = 0.5 * d->vdsat * dKk_dVc / Kk; dVdsat_dVd = T8 * dVgeff_dVd - T9 * dVc_dVd; dVdsat_dVg = T8 * dVgeff_dVg - T9 * dVc_dVg; dVdsat_dVb = T8 * dVgeff_dVb - T9 * dVc_dVb - d->vdsat*Inv_Aa*dAa_dVb; trace3("", T8, T9, d->vdsat); trace3("", dVdsat_dVd, dVdsat_dVg, dVdsat_dVb); } double Beta, dBeta_dVd, dBeta_dVg, dBeta_dVb; { double Beta0 = s->beta0 + s->beta0B * Vbs; double Betas = s->betas0 + s->betasB * Vbs; double Beta2 = s->beta20 + s->beta2B * Vbs + s->beta2G * Vgs; double Beta3 = s->beta30 + s->beta3B * Vbs + s->beta3G * Vgs; double Beta4 = s->beta40 + s->beta4B * Vbs + s->beta4G * Vgs; double Beta1 = Betas - (Beta0 + m->vdd * (Beta3 - m->vdd * Beta4)); trace4("", Beta0, s->beta0, s->beta0B, Vbs); trace4("", Betas, s->betas0, s->betasB, Vgs); trace4("", Beta2, s->beta20, s->beta2B, s->beta2G); trace4("", Beta3, s->beta30, s->beta3B, s->beta3G); trace4("", Beta4, s->beta40, s->beta4B, s->beta4G); trace2("", Beta1, m->vdd); double T0 = Vds * Beta2 / d->vdsat; T0 = std::min(T0, 30.0); double T1 = exp(T0); double T2 = T1 * T1; double T3 = T2 + 1.0; trace4("", T0, T1, T2, T3); double tanh = (T2 - 1.0) / T3; double Sqrsech = 4.0 * T2 / (T3 * T3); trace2("", tanh, Sqrsech); Beta = Beta0 + Beta1 * tanh + Vds * (Beta3 - Beta4 * Vds); double T4 = Beta1 * Sqrsech / d->vdsat; double T5 = m->vdd * tanh; dBeta_dVd = Beta3 - 2.0*Beta4*Vds + T4*(Beta2-T0*dVdsat_dVd); dBeta_dVg = T4 * (s->beta2G * Vds - T0 * dVdsat_dVg) + s->beta3G * (Vds - T5) - s->beta4G * (Vds * Vds - m->vdd * T5); double dBeta1_dVb = s->Arg; dBeta_dVb = s->beta0B + dBeta1_dVb * tanh + Vds * (s->beta3B - Vds * s->beta4B) + T4 * (s->beta2B * Vds - T0 * dVdsat_dVb); trace3("", T4, T5, dBeta1_dVb); trace4("", Beta, dBeta_dVd, dBeta_dVg, dBeta_dVb); } if (d->vgst > s->vglow) { // not subthreshold d->subthreshold = false; if (Vds <= d->vdsat) { // triode region d->saturated = false; double T3 = Vds / d->vdsat; double T4 = T3 - 1.0; double T2 = 1.0 - s->u1D * T4 * T4; double U1 = U1s * T2; double Utot = Uvert + U1 * Vds; Utot = std::max(Utot, 0.5); double Inv_Utot = 1.0 / Utot; double T5 = 2.0 * U1s * s->u1D * T4 / d->vdsat; double dU1_dVd = T5 * (T3 * dVdsat_dVd - 1.0); double dU1_dVg = T5 * T3 * dVdsat_dVg; double dU1_dVb = T5 * T3 * dVdsat_dVb + s->u1B * T2; double dUtot_dVd = dUvert_dVd + U1 + Vds * dU1_dVd; double dUtot_dVg = dUvert_dVg + Vds * dU1_dVg; double dUtot_dVb = dUvert_dVb + Vds * dU1_dVb; double tmp1 = (Vgeff - 0.5 * Aa * Vds); double tmp3 = tmp1 * Vds; double Betaeff = Beta * Inv_Utot; d->ids = Betaeff * tmp3; double T6 = d->ids / Betaeff * Inv_Utot; d->gds = T6 * (dBeta_dVd - Betaeff * dUtot_dVd) + Betaeff * (tmp1 + (dVgeff_dVd - 0.5 * Aa) * Vds); d->gmf = T6 * (dBeta_dVg - Betaeff * dUtot_dVg) + Betaeff * Vds * dVgeff_dVg; d->gmbf = T6 * (dBeta_dVb - Betaeff * dUtot_dVb) + Betaeff * Vds * (dVgeff_dVb - 0.5 * Vds * dAa_dVb); }else{ // Saturation d->saturated = true; double Inv_Kk = 1.0 / Kk; double tmp1 = Vgeff * Inv_Aa * Inv_Kk; double tmp3 = 0.5 * Vgeff * tmp1; double Betaeff = Beta * Inv_Uvert; d->ids = Betaeff * tmp3; double T0 = d->ids / Betaeff * Inv_Uvert; double T1 = Betaeff * Vgeff * Inv_Aa * Inv_Kk; double T2 = d->ids * Inv_Kk * dKk_dVc; if (s->ai0 != 0.0) { double Ai = s->ai0 + s->aiB * Vbs; double Bi = s->bi0 + s->biB * Vbs; double T5 = Bi / (Vds - d->vdsat); T5 = std::min(T5, 30.0); double T6 = exp(-T5); double FR = 1.0 + Ai * T6; double T7 = T5 / (Vds - d->vdsat); double T8 = (1.0 - FR) * T7; double dFR_dVd = T8 * (dVdsat_dVd - 1.0); double dFR_dVg = T8 * dVdsat_dVg; double dFR_dVb = T8 * dVdsat_dVb + T6 * (s->aiB - Ai * s->biB / (Vds - d->vdsat)); d->gds = (T0 * (dBeta_dVd - Betaeff * dUvert_dVd) + T1 * dVgeff_dVd - T2 * dVc_dVd) * FR + d->ids * dFR_dVd; d->gmf = (T0 * (dBeta_dVg - Betaeff * dUvert_dVg) + T1 * dVgeff_dVg - T2 * dVc_dVg) * FR + d->ids * dFR_dVg; d->gmbf = (T0 * (dBeta_dVb - Betaeff * dUvert_dVb) + T1 * dVgeff_dVb - T2 * dVc_dVb - d->ids * Inv_Aa * dAa_dVb) * FR + d->ids * dFR_dVb; d->ids *= FR; }else{ d->gds = T0 * (dBeta_dVd - Betaeff * dUvert_dVd) + T1 * dVgeff_dVd - T2 * dVc_dVd; d->gmf = T0 * (dBeta_dVg - Betaeff * dUvert_dVg) + T1 * dVgeff_dVg - T2 * dVc_dVg; d->gmbf = T0 * (dBeta_dVb - Betaeff * dUvert_dVb) + T1 * dVgeff_dVb - T2 * dVc_dVb - d->ids * Inv_Aa * dAa_dVb; } } }else{ // subthreshold d->subthreshold = true; assert(Exp0 != NOT_VALID); double T0 = Exp0 * Exp0; assert(Exp1 != NOT_VALID); double T1 = Exp1; trace4("sub", Exp0, Exp1, T0, T1); trace2("", n, m->Vtm); d->ids = Beta * m->Vtm * m->Vtm * T0 * (1.0 - T1); double T2 = d->ids / Beta; double T4 = n * m->Vtm; double T3 = d->ids / T4; trace4("", d->ids, T2, T4, T3); double FR, dFR_dVd, dFR_dVg, dFR_dVb; if ((Vds > d->vdsat) && s->ai0 != 0.0) { d->saturated = true; double Ai = s->ai0 + s->aiB * Vbs; double Bi = s->bi0 + s->biB * Vbs; double T5 = Bi / (Vds - d->vdsat); trace3("", Ai, Bi, T5); T5 = std::min(T5, 30.0); double T6 = exp(-T5); FR = 1.0 + Ai * T6; double T7 = T5 / (Vds - d->vdsat); double T8 = (1.0 - FR) * T7; trace4("", T5, T6, T7, T8); dFR_dVd = T8 * (dVdsat_dVd - 1.0); dFR_dVg = T8 * dVdsat_dVg; dFR_dVb = T8 * dVdsat_dVb + T6 * (s->aiB-Ai*s->biB/(Vds-d->vdsat)); trace4("ai0!=0", FR, dFR_dVd, dFR_dVg, dFR_dVb); }else{ d->saturated = false; FR = 1.0; dFR_dVd = 0.0; dFR_dVg = 0.0; dFR_dVb = 0.0; trace4("ai0==0", FR, dFR_dVd, dFR_dVg, dFR_dVb); } d->gds = (T2 * dBeta_dVd + T3 * (s->vofD * T4 - dVth_dVd - s->nD * d->vgst / n) + Beta * m->Vtm * T0 * T1) * FR + d->ids * dFR_dVd; d->gmf = (T2 * dBeta_dVg + T3) * FR + d->ids * dFR_dVg; d->gmbf = (T2 * dBeta_dVb + T3 * (s->vofB * T4 - dVth_dVb + s->nB * d->vgst / (n * T1s * T1s) * dT1s_dVb)) * FR + d->ids*dFR_dVb; d->ids *= FR; } }else{ // cutoff??? d->cutoff = true; // reachable only if vghigh and vgst both negative d->vdsat = 0.0; dVdsat_dVd = dVdsat_dVg = dVdsat_dVb = 0.0; d->ids = 0.0; d->gmf = 0.0; d->gds = 0.0; d->gmbf = 0.0; } trace4("", d->vdsat, dVdsat_dVd, dVdsat_dVg, dVdsat_dVb); trace4("", d->ids, d->gmf, d->gds, d->gmbf); /* Some Limiting of DC Parameters */ d->gds = std::max(d->gds, 1.0e-20); d->ids = std::max(d->ids, 1.0e-50); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ double Vbseff, dVbseff_dVb; if (Vbs < 0.0) { Vbseff = Vbs; dVbseff_dVb = 1.0; }else{ Vbseff = s->phi - Phisb; dVbseff_dVb = -dPhisb_dVb; } trace3("", Vbs, Vbseff, dVbseff_dVb); double Arg1 = Vgs - Vbseff - s->vfb; double Arg2 = Arg1 - d->vgst; trace2("", Arg1, Arg2); double Qbulk = s->One_Third_CoxWL * Arg2; double dQbulk_dVb = s->One_Third_CoxWL * (dVth_dVb - dVbseff_dVb); double dQbulk_dVd = s->One_Third_CoxWL * dVth_dVd; trace3("", Qbulk, dQbulk_dVb, dQbulk_dVd); if (Arg1 <= 0.0) { // accumulation region d->qgate = s->cgate * Arg1; d->qbulk = -(d->qgate); d->qdrn = 0.0; d->cggb = s->cgate; d->cgdb = 0.0; d->cgsb = -d->cggb * (1.0 - dVbseff_dVb); d->cdgb = 0.0; d->cddb = 0.0; d->cdsb = 0.0; d->cbgb = -s->cgate; d->cbdb = 0.0; d->cbsb = -d->cgsb; trace4("", d->qgate, d->cggb, d->cgdb, d->cgsb); trace4("", d->qbulk, d->cbgb, d->cbdb, d->cbsb); trace4("acc", d->qdrn, d->cdgb, d->cddb, d->cdsb); }else if (d->vgst <= 0.0) { // subthreshold double T2 = Arg1 / Arg2; double T3 = T2 * T2 * (s->cgate - s->Two_Third_CoxWL * T2); d->qgate = s->cgate * Arg1 * (1.0 - T2 * (1.0 - T2 / 3.0)); d->qbulk = -(d->qgate); d->qdrn = 0.0; d->cggb = s->cgate * (1.0 - T2 * (2.0 - T2)); d->cgdb = T3 * dVth_dVd; double tmp = T3 * dVth_dVb - (d->cggb + T3) * dVbseff_dVb; d->cgsb = -(d->cggb + d->cgdb + tmp); d->cbgb = -d->cggb; d->cbdb = -d->cgdb; d->cbsb = -d->cgsb; d->cdgb = 0.0; d->cddb = 0.0; d->cdsb = 0.0; trace3("", T2, T3, tmp); trace4("", d->qgate, d->cggb, d->cgdb, d->cgsb); trace4("", d->qbulk, d->cbgb, d->cbdb, d->cbsb); trace4("sub", d->qdrn, d->cdgb, d->cddb, d->cdsb); }else{ double Vdsat; // changes dVdsat_dVd, dVdsat_dVg, dVdsat_dVb; if (d->vgst < s->vghigh) { double Uvert = 1.0 + d->vgst * (Ua + d->vgst * Ub); Uvert = std::max(Uvert, 0.2); double Inv_Uvert = 1.0 / Uvert; double dUvert_dVg = Ua + 2.0 * Ub * d->vgst; double dUvert_dVd = -dUvert_dVg * dVth_dVd; double dUvert_dVb = -dUvert_dVg * dVth_dVb + d->vgst * (s->uaB + d->vgst * s->ubB); trace2("", Uvert, Inv_Uvert); trace3("", dUvert_dVg, dUvert_dVd, dUvert_dVb); double T8 = U1s * Inv_Aa * Inv_Uvert; double Vc = T8 * d->vgst; double T9 = Vc * Inv_Uvert; double dVc_dVg = T8 - T9 * dUvert_dVg; double dVc_dVd = -T8 * dVth_dVd - T9 * dUvert_dVd; double dVc_dVb = -T8 * dVth_dVb + s->u1B * d->vgst * Inv_Aa * Inv_Uvert - Vc * Inv_Aa * dAa_dVb - T9 * dUvert_dVb; trace3("", T8, T9, Vc); trace3("", dVc_dVg, dVc_dVd, dVc_dVb); double tmp2 = sqrt(1.0 + 2.0 * Vc); double Kk = 0.5 * (1.0 + Vc + tmp2); double dKk_dVc = 0.5 + 0.5 / tmp2; trace3("", tmp2, Kk, dKk_dVc); T8 = Inv_Aa / sqrt(Kk); Vdsat = d->vgst * T8; T9 = 0.5 * Vdsat * dKk_dVc / Kk; trace2("", T8, T9); dVdsat_dVd = -T8 * dVth_dVd - T9 * dVc_dVd; dVdsat_dVg = T8 - T9 * dVc_dVg; dVdsat_dVb = -T8*dVth_dVb - T9*dVc_dVb - Vdsat*Inv_Aa*dAa_dVb; trace2("new", d->vdsat, Vdsat); trace3("", dVdsat_dVd, dVdsat_dVg, dVdsat_dVb); }else{ Vdsat = d->vdsat; trace2("keep", d->vdsat, Vdsat); trace3("", dVdsat_dVd, dVdsat_dVg, dVdsat_dVb); // keep dVdsat_dVd, dVdsat_dVg, dVdsat_dVb; } if (Vds >= Vdsat) { /* saturation region */ d->cggb = s->Two_Third_CoxWL; d->cgdb = -d->cggb * dVth_dVd + dQbulk_dVd; double tmp = -d->cggb * dVth_dVb + dQbulk_dVb; d->cgsb = -(d->cggb + d->cgdb + tmp); trace1("", tmp); d->cbgb = 0.0; d->cbdb = -dQbulk_dVd; d->cbsb = dQbulk_dVd + dQbulk_dVb; d->cdgb = -0.4 * d->cggb; d->cddb = -d->cdgb * dVth_dVd; tmp = -d->cdgb * dVth_dVb; d->cdsb = -(d->cdgb + d->cddb + tmp); trace1("", tmp); d->qbulk = -Qbulk; d->qgate = s->Two_Third_CoxWL * d->vgst + Qbulk; d->qdrn = d->cdgb * d->vgst; trace4("", d->qgate, d->cggb, d->cgdb, d->cgsb); trace4("", d->qbulk, d->cbgb, d->cbdb, d->cbsb); trace4("sat", d->qdrn, d->cdgb, d->cddb, d->cdsb); }else{ /* linear region */ double T7 = Vds / Vdsat; double T8 = d->vgst / Vdsat; double T6 = T7 * T8; double T9 = 1.0 - T7; double Vgdt = d->vgst * T9; double T0 = d->vgst / (d->vgst + Vgdt); double T1 = Vgdt / (d->vgst + Vgdt); double T5 = T0 * T1; double T2 = 1.0 - T1 + T5; double T3 = 1.0 - T0 + T5; trace4("", T7, T8, T6, T9); trace2("", Vgdt, T0); trace4("", T1, T5, T2, T3); double dVgdt_dVg = T9 + T6 * dVdsat_dVg; double dVgdt_dVd = T6 * dVdsat_dVd - T8 -T9 * dVth_dVd; double dVgdt_dVb = T6 * dVdsat_dVb -T9 * dVth_dVb; trace3("", dVgdt_dVg, dVgdt_dVd, dVgdt_dVb); d->qgate = s->Two_Third_CoxWL * (d->vgst + Vgdt - Vgdt * T0) + Qbulk; d->qbulk = -Qbulk; d->qdrn = -s->One_Third_CoxWL * (0.2 * Vgdt + 0.8 * d->vgst + Vgdt * T1 + 0.2 * T5 * (Vgdt - d->vgst)); d->cggb = s->Two_Third_CoxWL * (T2 + T3 * dVgdt_dVg); d->cgdb = s->Two_Third_CoxWL * (T3*dVgdt_dVd-T2*dVth_dVd) + dQbulk_dVd; double tmp = dQbulk_dVb +s->Two_Third_CoxWL*(T3*dVgdt_dVb-T2*dVth_dVb); d->cgsb = -(d->cggb + d->cgdb + tmp); trace1("", tmp); T2 = 0.8 - 0.4 * T1 * (2.0 * T1 + T0 + T0 * (T1 - T0)); T3 = 0.2 + T1 + T0 * (1.0 - 0.4 * T0 * (T1 + 3.0 * T0)); d->cdgb = -s->One_Third_CoxWL * (T2 + T3 * dVgdt_dVg); d->cddb = s->One_Third_CoxWL * (T2 * dVth_dVd - T3 * dVgdt_dVd); tmp = s->One_Third_CoxWL * (T2 * dVth_dVb - T3 * dVgdt_dVb); d->cdsb = -(d->cdgb + tmp + d->cddb); trace3("", T2, T3, tmp); d->cbgb = 0.0; d->cbdb = -dQbulk_dVd; d->cbsb = dQbulk_dVd + dQbulk_dVb; trace4("", d->qgate, d->cggb, d->cgdb, d->cgsb); trace4("", d->qbulk, d->cbgb, d->cbdb, d->cbsb); trace4("lin", d->qdrn, d->cdgb, d->cddb, d->cdsb); } } if (d->reversed) { d->ids *= -1; d->gmr = d->gmf; d->gmbr = d->gmbf; d->gmf = d->gmbf = 0; }else{ d->gmr = d->gmbr = 0.; } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_mos6.model������������������������������������������������������������������������������������0000664�0000000�0000000�00000015654�11454012162�0014065�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: d_mos6.model,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * mos model equations: spice level 6 equivalent */ h_headers { #include "d_mos123.h" } cc_headers { #include "l_denoise.h" } /*--------------------------------------------------------------------------*/ model BUILT_IN_MOS6 { level 6; public_keys { nmos6 polarity=pN; pmos6 polarity=pP; } dev_type BUILT_IN_MOS; inherit BUILT_IN_MOS123; independent { override { double lambda0 "" name=LAMBDA; double mjsw "" default=.5; double cox "" final_default=0.; double vto "" final_default=0.; double gamma "" final_default=0.; double phi "" final_default=.6; int mos_level "back-annotate for diode" name=DIODElevel print_test="mos_level != LEVEL" default=LEVEL; } raw_parameters { double kv "Saturation voltage factor" name=KV default=2.0; double nv "Saturation voltage coeff." name=NV default=0.5; double kc "Saturation current factor" name=KC default=NA final_default=5e-5 print_test="!calc_kc"; double nc "Saturation current coeff." name=NC default=1.0; double nvth "Threshold voltage coeff." name=NVTH default=0.5; double ps "Sat. current modification par." name=PS default=0.0; double gamma1 "Bulk threshold parameter 1" name=GAMMA1 default=0.0; double sigma "Static feedback effect par." name=SIGMA default=0.0; double lambda0 "Channel length modulation param" name=LAMBDA0 default=0.0; double lambda1 "Channel length modulation param. 1" name=LAMBDA1 default=0.0; } calculated_parameters { bool calc_kc "" default=false; } code_pre { if (tox != NA) { cox = P_EPS_OX / tox; if (kc == NA) { kc = .5 * uo * cox; calc_kc = true; } if (nsub != NA) { if (phi == NA) { phi = (2. * P_K_Q) * tnom_k * log(nsub/NI); if (phi < .1) { untested(); error(((!_sim->is_first_expand()) ? (bDEBUG) : (bWARNING)), long_label() + ": calculated phi too small, using .1\n"); phi = .1; } calc_phi = true; } if (gamma == NA) { gamma = sqrt(2. * P_EPS_SI * P_Q * nsub) / cox; calc_gamma = true; } if (vto == NA) { double phi_ms = (tpg == gtMETAL) ? polarity * (-.05 - (egap + polarity * phi) / 2.) : -(tpg * egap + phi) / 2.; double vfb = phi_ms - polarity * P_Q * nss / cox; vto = vfb + phi + gamma * sqrt(phi); calc_vto = true; } } } } } temperature_dependent { calculated_parameters { double phi "" calculate="m->phi*tempratio + (-2*vt*(1.5*log(tempratio)+P_Q*(arg)))"; double beta "" calculate="(m->kc / tempratio4) * s->w_eff / s->l_eff"; double vbi "" calculate="(fixzero( (m->vto - m->gamma * sqrt(m->phi) +.5*(m->egap-egap) + m->polarity* .5 * (phi-m->phi)), m->phi))"; } code_pre { double temp = d->_sim->_temp_c + P_CELSIUS0; double tempratio = temp / m->tnom_k; double tempratio4 = tempratio * sqrt(tempratio); double kt = temp * P_K; double vt = temp * P_K_Q; double egap = 1.16 - (7.02e-4*temp*temp) / (temp+1108.); double arg = (m->egap*tempratio - egap) / (2*kt); } } /*-----------------------------------------------------------------------*/ tr_eval { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ trace1(d->long_label().c_str(), d->evaliter()); trace3("", d->vds, d->vgs, d->vbs); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ d->reverse_if_needed(); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ double sarg; if (d->vbs <= 0.) { d->sbfwd = false; sarg = sqrt(t->phi - d->vbs); }else{ d->sbfwd = true; sarg = sqrt(t->phi); sarg = sarg - d->vbs / (sarg+sarg); if (sarg < 0.) { untested(); sarg = 0.; }else{ untested(); } } trace3("", t->phi, d->vbs, sarg); assert(sarg >= 0.); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ trace4("", d->vds, t->vbi, m->gamma, m->gamma1); d->von = t->vbi + m->gamma * sarg - m->gamma1 * d->vbs; // - m->sigma * d->vds; // what is this????? d->vgst = d->vgs - d->von; trace3("", d->vds, d->von, d->vgst); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ d->cutoff = (d->vgst <= 0.); if (d->cutoff) { d->vdsat = 0.; d->ids = d->gmf = d->gds = d->gmbf = 0.; trace4("cut", d->ids, d->gmf, d->gds, d->gmbf); }else{ double vonbm; if (d->vbs <= 0.) { vonbm = m->gamma1 + m->gamma / (sarg + sarg); }else{ vonbm = m->gamma1 + m->gamma * .5 / sqrt(t->phi); untested(); } trace3("", m->nc, m->lambda0, m->lambda1); double logvgon = log(d->vgst); double idsat = t->beta * exp(logvgon * m->nc); double Lambda = m->lambda0 - m->lambda1 * d->vbs; trace4("", vonbm, logvgon, idsat, Lambda); d->ids = idsat * (1 + Lambda * d->vds); d->gmf = d->ids * m->nc / d->vgst; d->gds = d->gmf * m->sigma + idsat * Lambda; d->gmbf = d->gmf * vonbm - idsat * m->lambda1 * d->vds; d->vdsat = m->kv * exp(logvgon * m->nv); trace4("sat", d->ids, d->gmf, d->gds, d->gmbf); d->saturated = (d->vdsat <= d->vds); if (!d->saturated) { double vdst = d->vds / d->vdsat; double vdst2 = (2 - vdst) * vdst; double vdstg = - vdst * m->nv / d->vgst; double ivdst1 = d->ids * (2 - vdst - vdst); d->ids *= vdst2; d->gmf = d->gmf * vdst2 + ivdst1 * vdstg; d->gds = d->gds * vdst2 + ivdst1 * (1 / d->vdsat + vdstg * m->sigma); d->gmbf = d->gmbf * vdst2 + ivdst1 * vdstg * vonbm; trace4("lin", d->ids, d->gmf, d->gds, d->gmbf); } } if (d->reversed) { d->ids *= -1; d->gmr = d->gmf; d->gmbr = d->gmbf; d->gmf = d->gmbf = 0; }else{ d->gmr = d->gmbr = 0.; } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ������������������������������������������������������������������������������������src/d_mos7.model������������������������������������������������������������������������������������0000664�0000000�0000000�00000224074�11454012162�0014064�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: d_mos7.model,v 26.132 2009/11/24 04:26:37 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Berkeley BSIM3v3.1 model * Derived from Spice3f4,Copyright 1990 Regents of the University of California * Author: 1991 JianHui Huang and Min-Chie Jeng. * Recoded for Gnucap model compiler, Al Davis, 2000 */ h_headers { #include "d_mos_base.h" } cc_headers { #include "l_compar.h" #include "l_denoise.h" } /*--------------------------------------------------------------------------*/ /* from diode no fc??? double bulkJctPotential "Source/drain junction built-in potential" name=PB default=1.0; double unitAreaJctCap "Source/drain bottom junction capacitance per unit area" name=CJ default=5.0E-4; double bulkJctBotGradingCoeff "Source/drain bottom junction capacitance grading coefficient" name=MJ default=0.5; double sidewallJctPotential "Source/drain sw junction capacitance built in potential" name=PBSW default=1.0; double unitLengthSidewallJctCap "Source/drain sw junction capacitance per unit periphery" name=CJSW default=5.0E-10; double bulkJctSideGradingCoeff "Source/drain sw junction capacitance grading coefficient" name=MJSW default=0.33; double kf "Flicker noise coefficient" name=KF default=0.0; double af "Flicker noise exponent" name=AF default=1.0; from mos_base no is??? double jctSatCurDensity "Source/drain junction reverse saturation current density" name=JS default=1.0E-4; double sheetResistance "Source-drain sheet resistance" name=RSH default=0.0; no rd??? no rs??? no cbd??? no cbs??? double cgso "Gate-source overlap capacitance per width" "CGSO default=NA; double cgdo "Gate-drain overlap capacitance per width" name=CGDO default=NA; double cgbo "Gate-bulk overlap capacitance per length" name=CGBO default=NA; */ model BUILT_IN_MOS7 { level 7 public_keys { nmos7 polarity=pN; pmos7 polarity=pP; } dev_type BUILT_IN_MOS; inherit BUILT_IN_MOS_BASE; independent { override { double mjsw "" final_default=.33; double pb "" final_default=1.0 quiet_min=0.1; double pbsw "" final_default=pb quiet_min=0.1; double cjo "" default=5.0E-4; double cgdo "" final_default="(((dlc != NA) && (dlc > 0.0)) ? dlc * cox - cgdl.nom() : 0.6 * xj.nom() * cox)"; double cgso "" final_default="(((dlc != NA) && (dlc > 0.0)) ? dlc * cox - cgsl.nom() : 0.6 * xj.nom() * cox)"; double cgbo "" final_default="((dwc != NA) ? 2.0 * dwc * cox : 2.0 * Wint * cox)"; /* assumes cg?? final_default is BEFORE d?c final_default */ int cmodel "CMODEL" print_test="cmodel!=1" calculate="((!cmodel)?1:cmodel)"; bool needs_isub "" calculate="(alpha0.nom()!=0.)"; int mos_level "back-annotate for diode" name=DIODElevel print_test="mos_level != LEVEL" default=LEVEL; } raw_parameters { int capMod "Capacitance model selector (0, 1, 2, other?)" name=CAPMOD default=2; int nqsMod "Non-quasi-static model selector (0, !0)" name=NQSMOD default=0; int mobMod "Mobility model selector (1,2,3,other?)" name=MOBMOD default=1; int noiMod "Noise model selector (not used)" name=NOIMOD default=1; int paramChk "Model parameter checking selector (not used)" name=PARAMCHK default=0; int binUnit "Bin unit selector (1, !1)" name=BINUNIT default=1; double version "parameter for model version (not used)" name=VERSION default=3.1; double tox "Gate oxide thickness in meters" name=TOX default=150.0e-10; double xpart "Channel charge partitioning" name=XPART default=0.0; double jctSidewallSatCurDensity "Sidewall junction reverse saturation current density" name=JSW default=0.0; double mjswg "Source/drain (gate side) sw junction capacitance grading coefficient" name=MJSWG default=NA final_default=mjsw; double pbswg "Source/drain (gate side) sw junction capacitance built in potential" name=PBSWG default=NA final_default=pbsw quiet_min=0.1; double unitLengthGateSidewallJctCap "Source/drain (gate side) sidewall junction capacitance per unit width" name=CJSWG default=NA final_default=cjsw; double jctEmissionCoeff "Source/drain junction emission coefficient" name=NJ default=1.0; double jctTempExponent "Junction current temperature exponent" name=XTI default=3.0; double Lint "Length reduction parameter" name=LINT default=0.0; double Ll "Length reduction parameter" name=LL default=0.0; double Lln "Length reduction parameter" name=LLN default=1.0; double Lw "Length reduction parameter" name=LW default=0.0; double Lwn "Length reduction parameter" name=LWN default=1.0; double Lwl "Length reduction parameter" name=LWL default=0.0; double Wint "Width reduction parameter" name=WINT default=0.0; double Wl "Width reduction parameter" name=WL default=0.0; double Wln "Width reduction parameter" name=WLN default=1.0; double Ww "Width reduction parameter" name=WW default=0.0; double Wwn "Width reduction parameter" name=WWN default=1.0; double Wwl "Width reduction parameter" name=WWL default=0.0; double dwc "Delta W for C-V model" name=DWC default=NA final_default=Wint; double dlc "Delta L for C-V model" name=DLC default=NA final_default=Lint; double noia "Flicker noise parameter, oxide trap density A" name=NOIA default=NA final_default="(polarity==pN) ? 1e20 : 9.9e18"; double noib "Flicker noise parameter, oxide trap density B" name=NOIB default=NA final_default="(polarity==pN) ? 5e4 : 2.4e3"; double noic "Flicker noise parameter, oxide trap density C" name=NOIC default=NA final_default="(polarity==pN) ?-1.4e-12 :1.4e-12"; double em "Flicker noise parameter V/m" name=EM default=4.1e7; double ef "Flicker noise frequency exponent" name=EF default=1.0; } calculated_parameters { double cox; double factor1 "" calculate="sqrt(tox * P_EPS_SI / P_EPS_OX)"; double vt_at_tnom "" calculate="tnom_k * P_K_Q"; double ni "" calculate="(1.45e10 * (tnom_k / 300.15) * sqrt(tnom_k / 300.15) * exp(21.5565981 - egap / (2.0 * vt_at_tnom)))"; } code_pre { //tox = std::max(tox, 1e-20); cox = 3.453133e-11 / tox; } code_post { if (npeak.has_good_value() && npeak.nom() > 1.0e20) { npeak.set_nom(npeak.nom() * 1.0e-6); } if (ngate.has_good_value() && ngate.nom() > 1.0e23) { ngate.set_nom(ngate.nom() * 1.0e-6); } } } size_dependent { raw_parameters { double cdsc "Drain/Source and channel coupling capacitance Q/V/m^2" name=CDSC default=2.4e-4; double cdscb "Body-bias dependence of cdsc Q/V/m^2" name=CDSCB default=0.0; double cdscd "Drain-bias dependence of cdsc Q/V/m^2" name=CDSCD default=0.0; double cit "Interface state capacitance Q/V/m^2" name=CIT default=0.0; double nfactor "Subthreshold swing Coefficient" name=NFACTOR default=1; double xj "Junction depth in meters" name=XJ default=.15e-6; double vsat "Saturation velocity at tnom m/s" name=VSAT default=8.0e4; double at "Temperature coefficient of vsat m/s" name=AT default=3.3e4; double a0 "Non-uniform depletion width effect coefficient." name=A0 default=1.0; double ags "Gate bias coefficient of Abulk." name=AGS default=0.0; double a1 "Non-saturation effect coefficient" name=A1 default=0.0; double a2 "Non-saturation effect coefficient" name=A2 default=1.0; double keta "Body-bias coefficient of non-uniform depletion width effect. 1/v" name=KETA default=-0.047; double nsub "Substrate doping concentration 1/cm3" name=NSUB default=6.0e16; double npeak "Channel doping concentration 1/cm3" name=NCH default=NA; double ngate "Poly-gate doping concentration 1/cm3" name=NGATE default=0.0; double gamma1 "Vth body coefficient" name=GAMMA1 default=NA; double gamma2 "Vth body coefficient" name=GAMMA2 default=NA; double vbx "Vth transition body Voltage" name=VBX default=NA; double vbm "Maximum body voltage" name=VBM default=-3.0; double xt "Doping depth" name=XT default=1.55e-7; double k1 "Bulk effect coefficient 1" name=K1 default=NA; double kt1 "Temperature coefficient of Vth" name=KT1 default=-0.11; double kt1l "Temperature coefficient of Vth" name=KT1L default=0.0; double kt2 "Body-coefficient of kt1" name=KT2 default=0.022; double k2 "Bulk effect coefficient 2" name=K2 default=NA; double k3 "Narrow width effect coefficient" name=K3 default=80.0; double k3b "Body effect coefficient of k3" name=K3B default=0.0; double w0 "Narrow width effect parameter" name=W0 default=2.5e-6; double nlx "Lateral non-uniform doping effect" name=NLX default=1.74e-7; double dvt0 "Short channel effect coeff. 0" name=DVT0 default=2.2; double dvt1 "Short channel effect coeff. 1" name=DVT1 default=0.53; double dvt2 "Short channel effect coeff. 2 1/v" name=DVT2 default=-0.032; double dvt0w "Narrow Width coeff. 0" name=DVT0W default=0.0; double dvt1w "Narrow Width effect coeff. 1" name=DVT1W default=5.3e6; double dvt2w "Narrow Width effect coeff. 2" name=DVT2W default=-0.032; double drout "DIBL coefficient of output resistance" name=DROUT default=0.56; double dsub "DIBL coefficient in the subthreshold region" name=DSUB default=NA final_default="drout"; double vth0 "Threshold voltage" name=VTH0 default=NA final_default=NA; double ua1 "Temperature coefficient of ua m/v" name=UA1 default=4.31e-9; double ua "Linear gate dependence of mobility m/v" name=UA default=2.25e-9; double ub1 "Temperature coefficient of ub (m/V)**2" name=UB1 default=-7.61e-18; double ub "Quadratic gate dependence of mobility (m/V)**2" name=UB default=5.87e-19; double uc1 "Temperature coefficient of uc" name=UC1 default=NA final_default="((m->mobMod==3) ? -0.056 : -0.056e-9)"; double uc "Body-bias dependence of mobility" name=UC default=NA final_default="((m->mobMod==3) ? -0.0465 : -0.0465e-9)"; double u0 "Low-field mobility at Tnom" name=U0 default=NA final_default="((m->polarity == pN) ? 0.067 : 0.025)"; double ute "Temperature coefficient of mobility" name=UTE default=-1.5; double voff "Threshold voltage offset" name=VOFF default=-0.08; double delta "Effective Vds parameter" name=DELTA default=0.01; double rdsw "Source-drain resistance per width" name=RDSW default=0.0; double prwg "Gate-bias effect on parasitic resistance" name=PRWG default=0.0; double prwb "Body-effect on parasitic resistance" name=PRWB default=0.0; double prt "Temperature coefficient of parasitic resistance" name=PRT default=0.0; double eta0 "Subthreshold region DIBL coefficient" name=ETA0 default=0.08; double etab "Subthreshold region DIBL coefficient 1/v" name=ETAB default=-0.07; double pclm "Channel length modulation Coefficient" name=PCLM default=1.3; double pdibl1 "Drain-induced barrier lowering coefficient" name=PDIBLC1 default=.39; double pdibl2 "Drain-induced barrier lowering coefficient" name=PDIBLC2 default=0.0086; double pdiblb "Body-effect on drain-induced barrier lowering 1/v" name=PDIBLCB default=0.0; double pscbe1 "Substrate current body-effect coefficient" name=PSCBE1 default=4.24e8; double pscbe2 "Substrate current body-effect coefficient" name=PSCBE2 default=1.0e-5; double pvag "Gate dependence of output resistance parameter" name=PVAG default=0.0; double wr "Width dependence of rds" name=WR default=1.0; double dwg "Width reduction parameter" name=DWG default=0.0; double dwb "Width reduction parameter" name=DWB default=0.0; double b0 "Abulk narrow width parameter" name=B0 default=0.0; double b1 "Abulk narrow width parameter" name=B1 default=0.0; double alpha0 "substrate current model parameter" name=ALPHA0 default=0.0; double beta0 "substrate current model parameter" name=BETA0 default=30.0; /* CV model */ double elm "Non-quasi-static Elmore Constant Parameter" name=ELM default=5.0; double vfbcv "Flat Band Voltage parameter for capmod=0 only" name=VFBCV default=-1.0; double cgsl "New C-V model parameter" name=CGSL default=0.0; double cgdl "New C-V model parameter" name=CGDL default=0.0; double ckappa "New C-V model parameter" name=CKAPPA default=0.6; double cf "Fringe capacitance parameter" name=CF default=NA final_default="2.0 * P_EPS_OX / M_PI * log(1.0 + 0.4e-6 / m->tox)"; double clc "Vdsat parameter for C-V model" name=CLC default=0.1e-6; double cle "Vdsat parameter for C-V model" name=CLE default=0.6; } calculated_parameters { double dl; double dlc; double dw; double dwc; double leff; /* BUG:: why not reuse from super */ double weff; double leffCV; double weffCV; double abulkCVfactor "" calculate="1.0 + pow((clc / leff), cle)"; double cgso "" calculate="(m->cgso + cf) * weffCV"; double cgdo "" calculate="(m->cgdo + cf) * weffCV"; double cgbo "" calculate="m->cgbo * leffCV"; double litl "" calculate="sqrt(3.0 * xj * m->tox)"; } code_pre { { double T0 = pow(c->l_in, m->Lln); double T1 = pow(c->w_in, m->Lwn); double tmp1 = m->Ll / T0 + m->Lw / T1 + m->Lwl / (T0 * T1); dl = m->Lint + tmp1; dlc = m->dlc + tmp1; } { double T2 = pow(c->l_in, m->Wln); double T3 = pow(c->w_in, m->Wwn); double tmp2 = m->Wl / T2 + m->Ww / T3 + m->Wwl / (T2 * T3); dw = m->Wint + tmp2; dwc = m->dwc + tmp2; } leff = c->l_in - 2.0 * dl; weff = c->w_in - 2.0 * dw; leffCV = c->l_in - 2.0 * dlc; weffCV = c->w_in - 2.0 * dwc; cgate = m->cox * w_eff * l_eff; /* BUG:: not adjusted values?? */ double L = leff; double W = weff; if (m->binUnit == 1) { L /= MICRON2METER; W /= MICRON2METER; } } code_post { if (u0 > 1.0) { u0 /= 1.0e4; } if (m->npeak.nom() == NA) { if (m->gamma1.nom() != NA) { double T0 = gamma1 * m->cox; npeak = 3.021E22 * T0 * T0; }else{ npeak = 1.7e17; } } if (m->k1.nom() != NA && m->k2.nom() != NA) { if (m->k1.nom() == NA) { k1 = 0.53; } if (m->k2.nom() == NA) { k2 = -0.0186; } }else{ vbm = -std::abs(vbm); if (m->gamma1.nom() == NA) { gamma1 = 5.753e-12 * sqrt(npeak) / m->cox; } if (m->gamma2.nom() == NA) { gamma2 = 5.753e-12 * sqrt(nsub) / m->cox; } } } } temperature_dependent { calculated_parameters { double temp; double tempratio "" calculate="temp / m->tnom_k"; double tempratio_1 "" calculate="tempratio - 1"; double vtm "vtm" calculate="temp * P_K_Q"; double ua; double ub; double uc; double u0temp; double vsattemp; double rds0; double phi; double sqrtPhi; double phis3; double Xdep0; double vbi; double cdep0; double k1; double k2; double vbsc; double vth0; double vfb; double theta0vb0; double thetaRout; } code_pre { temp = d->_sim->_temp_c + P_CELSIUS0; double egap = 1.16 - 7.02e-4 * temp * temp / (temp + 1108.0); } code_post { double jctTempSatCurDensity; double jctSidewallTempSatCurDensity; if (temp != m->tnom_k) { double T0 = m->egap / m->vt_at_tnom - egap / vtm + m->jctTempExponent * log(temp / m->tnom_k); double T1 = exp(T0 / m->jctEmissionCoeff); jctTempSatCurDensity = m->js * T1; jctSidewallTempSatCurDensity = m->jctSidewallSatCurDensity * T1; }else{ jctTempSatCurDensity = m->js; jctSidewallTempSatCurDensity = m->jctSidewallSatCurDensity; } if (jctTempSatCurDensity < 0.0) { jctTempSatCurDensity = 0.0; } if (jctSidewallTempSatCurDensity < 0.0) { jctSidewallTempSatCurDensity = 0.0; } { double T0 = (tempratio - 1.0); ua = s->ua + s->ua1 * T0; ub = s->ub + s->ub1 * T0; uc = s->uc + s->uc1 * T0; u0temp = s->u0 * pow(tempratio, s->ute); vsattemp = s->vsat - s->at * T0; rds0 = (s->rdsw + s->prt * T0) / pow(s->weff * 1E6, s->wr); } phi = 2.0 * m->vt_at_tnom * log(s->npeak / m->ni); sqrtPhi = sqrt(phi); phis3 = sqrtPhi * phi; Xdep0 = sqrt(2.0 * P_EPS_SI / (P_Q * s->npeak * 1.0e6)) * sqrtPhi; vbi = m->vt_at_tnom * log(1.0e20 * s->npeak / (m->ni * m->ni)); cdep0 = sqrt(P_Q * P_EPS_SI * s->npeak * 1.0e6 / 2.0 / phi); if (m->k1.nom() != NA && m->k2.nom() != NA) { k2 = s->k2; k1 = s->k1; }else{ double vbx = (m->vbx.nom() == NA) ? -std::abs(phi - 7.7348e-4 * s->npeak * s->xt * s->xt) : -std::abs(s->vbx); double T0 = s->gamma1 - s->gamma2; double T1 = sqrt(phi - vbx) - sqrtPhi; double T2 = sqrt(phi * (phi - s->vbm)) - phi; k2 = T0 * T1 / (2.0 * T2 + s->vbm); k1 = s->gamma2 - 2.0 * k2 * sqrt(phi - s->vbm); } if (k2 < 0.) { double T0 = 0.5 * k1 / k2; vbsc = to_range(-30.0, (0.9 * (phi - T0 * T0)), -3.0); }else{ vbsc = -30.0; } vbsc = std::min(vbsc, s->vbm); if (s->vth0 == NA) { vfb = -1.0; vth0 = m->polarity * (vfb + phi + k1 * sqrtPhi); }else{ vth0 = s->vth0; vfb = m->polarity * vth0 - phi - k1 * sqrtPhi; } trace3("", s->vth0, vth0, vfb); { double T1 = sqrt(P_EPS_SI / P_EPS_OX * m->tox * Xdep0); double T0 = exp(-0.5 * s->dsub * s->leff / T1); theta0vb0 = (T0 + 2.0 * T0 * T0); T0 = exp(-0.5 * s->drout * s->leff / T1); double T2 = (T0 + 2.0 * T0 * T0); thetaRout = s->pdibl1 * T2 + s->pdibl2; } } } /*-----------------------------------------------------------------------*/ tr_eval { trace3("", d->vds, d->vgs, d->vbs); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const double EXP_THRESHOLD = 34.0; const double MIN_EXP = 1.713908431e-15; const double MAX_EXP = 5.834617425e14; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - d->reverse_if_needed(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double Vbseff, dVbseff_dVb; { double T0 = d->vbs - t->vbsc - 0.001; double T1 = sqrt(T0 * T0 - 0.004 * t->vbsc); trace3("", t->vbsc, T0, T1); Vbseff = t->vbsc + 0.5 * (T0 + T1); dVbseff_dVb = 0.5 * (1.0 + T0 / T1); trace2("raw", Vbseff, dVbseff_dVb); fixzero(&Vbseff, t->vbsc); if (Vbseff < d->vbs) { // From Spice, to fix numeric problems untested(); // inadequately. Above fixzero should do a Vbseff = d->vbs; // better job, but I left this in case. } } trace2("fixed", Vbseff, dVbseff_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double Phis, dPhis_dVb, sqrtPhis, dsqrtPhis_dVb; if (Vbseff > 0.0) { untested(); d->sbfwd = true; double T0 = t->phi / (t->phi + Vbseff); Phis = t->phi * T0; dPhis_dVb = -T0 * T0; sqrtPhis = t->phis3 / (t->phi + 0.5 * Vbseff); dsqrtPhis_dVb = -0.5 * sqrtPhis * sqrtPhis / t->phis3; trace0("bs-fwd-bias"); }else{ d->sbfwd = false; Phis = t->phi - Vbseff; dPhis_dVb = -1.0; sqrtPhis = sqrt(Phis); dsqrtPhis_dVb = -0.5 / sqrtPhis; trace0("bs-normal"); } trace4("", Phis, dPhis_dVb, sqrtPhis, dsqrtPhis_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double Xdep = t->Xdep0 * sqrtPhis / t->sqrtPhi; double dXdep_dVb = (t->Xdep0 / t->sqrtPhi) * dsqrtPhis_dVb; trace2("", Xdep, dXdep_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double Theta0, dTheta0_dVb; { double lt1, dlt1_dVb; { double T3 = sqrt(Xdep); double T0 = s->dvt2 * Vbseff; double T1, T2; if (T0 >= - 0.5) { T1 = 1.0 + T0; T2 = s->dvt2; trace4("", T0, T1, T2, T3); }else{ untested(); /* Added to avoid any discontinuity problems caused by dvt2 */ double T4 = 1.0 / (3.0 + 8.0 * T0); T1 = (1.0 + 3.0 * T0) * T4; T2 = s->dvt2 * T4 * T4; trace4("dvd2 fix", T0, T1, T2, T3); } lt1 = m->factor1 * T3 * T1; dlt1_dVb = m->factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2); } trace2("", lt1, dlt1_dVb); double T0 = -0.5 * s->dvt1 * s->leff / lt1; if (T0 > -EXP_THRESHOLD) { double T1 = exp(T0); Theta0 = T1 * (1.0 + 2.0 * T1); double dT1_dVb = -T0 / lt1 * T1 * dlt1_dVb; dTheta0_dVb = (1.0 + 4.0 * T1) * dT1_dVb; trace2("T0 > -ET", Theta0, dTheta0_dVb); }else{ double T1 = MIN_EXP; Theta0 = T1 * (1.0 + 2.0 * T1); dTheta0_dVb = 0.0; trace2("T0 < -ET", Theta0, dTheta0_dVb); } } trace2("", Theta0, dTheta0_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double dVth_dVb, dVth_dVd; // d->von { double V0 = t->vbi - t->phi; double T2, dT2_dVb; { double ltw, dltw_dVb; { double t3 = sqrt(Xdep); double t0 = s->dvt2w * Vbseff; double t1, t2; if (t0 >= - 0.5) { t1 = 1.0 + t0; t2 = s->dvt2w; }else{ untested(); /* Added to avoid any discontinuity problems caused by dvt2w */ double t4 = 1.0 / (3.0 + 8.0 * t0); t1 = (1.0 + 3.0 * t0) * t4; t2 = s->dvt2w * t4 * t4; } trace4("", t0, t1, t2, t3); ltw = m->factor1 * t3 * t1; dltw_dVb = m->factor1 * (0.5 / t3 * t1 * dXdep_dVb + t3 * t2); } trace2("", ltw, dltw_dVb); double T0 = -0.5 * s->dvt1w * s->weff * s->leff / ltw; if (T0 > -EXP_THRESHOLD) { double T1 = exp(T0); T2 = T1 * (1.0 + 2.0 * T1); double dT1_dVb = -T0 / ltw * T1 * dltw_dVb; dT2_dVb = (1.0 + 4.0 * T1) * dT1_dVb; }else{ double T1 = MIN_EXP; T2 = T1 * (1.0 + 2.0 * T1); dT2_dVb = 0.0; } T0 = s->dvt0w * T2; T2 = T0 * V0; dT2_dVb = s->dvt0w * dT2_dVb * V0; } trace3("", V0, T2, dT2_dVb); double T0 = sqrt(1.0 + s->nlx / s->leff); double T1 = t->k1 * (T0 - 1.0) * t->sqrtPhi + (s->kt1 + s->kt1l / s->leff + s->kt2 * Vbseff) * t->tempratio_1; double tmp2 = m->tox * t->phi / (s->weff + s->w0); double T3 = s->eta0 + s->etab * Vbseff; trace4("", T0, T1, tmp2, T3); double T4; if (T3 < 1.0e-4) { untested(); /* avoid discontinuity problems caused by etab */ double T9 = 1.0 / (3.0 - 2.0e4 * T3); T3 = (2.0e-4 - T3) * T9; T4 = T9 * T9; trace3("", T9, T3, T4); }else{ T4 = 1.0; trace1("", T4); } double thetavth = s->dvt0 * Theta0; double Delt_vth = thetavth * V0; double dDelt_vth_dVb = s->dvt0 * dTheta0_dVb * V0; trace4("", thetavth, t->theta0vb0, Delt_vth, dDelt_vth_dVb); double dDIBL_Sft_dVd = T3 * t->theta0vb0; double DIBL_Sft = dDIBL_Sft_dVd * d->vds; trace2("", dDIBL_Sft_dVd, DIBL_Sft); trace4("", t->vth0, t->k1, sqrtPhis, t->sqrtPhi); trace4("", t->k2, Vbseff, Delt_vth, T2); trace4("", s->k3, s->k3b, Vbseff, tmp2); trace2("", T1, DIBL_Sft); double Vth = m->polarity * t->vth0 + t->k1 * (sqrtPhis - t->sqrtPhi) - t->k2 * Vbseff - Delt_vth - T2 + (s->k3 + s->k3b * Vbseff) * tmp2 + T1 - DIBL_Sft; d->von = Vth; dVth_dVb = t->k1 * dsqrtPhis_dVb - t->k2 - dDelt_vth_dVb - dT2_dVb + s->k3b * tmp2 - s->etab * d->vds * t->theta0vb0 * T4 + s->kt2 * t->tempratio_1; dVth_dVd = -dDIBL_Sft_dVd; } trace3("", d->von, dVth_dVb, dVth_dVd); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Calculate n */ double n, dn_dVb, dn_dVd; { double tmp2 = s->nfactor * P_EPS_SI / Xdep; double tmp3 = s->cdsc + s->cdscb * Vbseff + s->cdscd * d->vds; double tmp4 = (tmp2 + tmp3 * Theta0 + s->cit) / m->cox; trace3("", tmp2, tmp3, tmp4); if (tmp4 >= -0.5) { n = 1.0 + tmp4; dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb + s->cdscb * Theta0) / m->cox; dn_dVd = s->cdscd * Theta0 / m->cox; trace3("n", n, dn_dVb, dn_dVd); }else{ /* avoid discontinuity problems caused by tmp4 */ double T0 = 1.0 / (3.0 + 8.0 * tmp4); n = (1.0 + 3.0 * tmp4) * T0; T0 *= T0; dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb + s->cdscb * Theta0) / m->cox * T0; dn_dVd = s->cdscd * Theta0 / m->cox * T0; trace3("n disc", n, dn_dVb, dn_dVd); } } trace3("", n, dn_dVb, dn_dVd); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Poly Gate Si Depletion Effect */ double Vgs_eff, dVgs_eff_dVg; { double T0 = t->vfb + t->phi; trace2("Poly", t->vfb, t->phi); trace3("", s->ngate, d->vgs, T0); if ((s->ngate > 1.e18) && (s->ngate < 1.e25) && (d->vgs > T0)) { /* added to avoid the problem caused by ngate */ double T1 = 1.0e6 * P_Q * P_EPS_SI * s->ngate / (m->cox * m->cox); double T4 = sqrt(1.0 + 2.0 * (d->vgs - T0) / T1); double T2 = T1 * (T4 - 1.0); double T3 = 0.5 * T2 * T2 / T1; /* T3 = Vpoly */ double T7 = 1.12 - T3 - 0.05; double T6 = sqrt(T7 * T7 + 0.224); double T5 = 1.12 - 0.5 * (T7 + T6); Vgs_eff = d->vgs - T5; dVgs_eff_dVg = 1.0 - (0.5 - 0.5 / T4) * (1.0 + T7 / T6); trace2("><", Vgs_eff, dVgs_eff_dVg); }else{ Vgs_eff = d->vgs; dVgs_eff_dVg = 1.0; trace2("const", Vgs_eff, dVgs_eff_dVg); } } trace2("", Vgs_eff, dVgs_eff_dVg); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Effective Vgst (Vgsteff) Calculation */ double /*Vgsteff,*/ dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb, Vgst2Vtm; double VgstNVt, ExpVgst; // d->vgst { double Vgst = Vgs_eff - d->von; double T10 = 2.0 * n * t->vtm; VgstNVt = Vgst / T10; double ExpArg = (2.0 * s->voff - Vgst) / T10; trace4("", Vgst, T10, VgstNVt, ExpArg); /* MCJ: Very small Vgst */ if (VgstNVt > EXP_THRESHOLD) { d->vgst = Vgst; dVgsteff_dVg = dVgs_eff_dVg; dVgsteff_dVd = -dVth_dVd; dVgsteff_dVb = -dVth_dVb; ExpVgst = NOT_VALID; trace4(">>", d->vgst, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb); }else if (ExpArg > EXP_THRESHOLD) { double T0 = (Vgst - s->voff) / (n * t->vtm); ExpVgst = exp(T0); d->vgst = t->vtm * t->cdep0 / m->cox * ExpVgst; dVgsteff_dVg = d->vgst / (n * t->vtm); dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + T0 * t->vtm * dn_dVd); dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + T0 * t->vtm * dn_dVb); dVgsteff_dVg *= dVgs_eff_dVg; trace4(">", d->vgst, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb); }else{ ExpVgst = exp(VgstNVt); double T1 = T10 * log(1.0 + ExpVgst); double dT1_dVg = ExpVgst / (1.0 + ExpVgst); double dT1_dVb = -dT1_dVg * (dVth_dVb + Vgst / n * dn_dVb) + T1 / n * dn_dVb; double dT1_dVd = -dT1_dVg * (dVth_dVd + Vgst / n * dn_dVd) + T1 / n * dn_dVd; double dT2_dVg = -m->cox / (t->vtm * t->cdep0) * exp(ExpArg); double T2 = 1.0 - T10 * dT2_dVg; double dT2_dVd = -dT2_dVg * (dVth_dVd - 2.0 * t->vtm * ExpArg * dn_dVd) + (T2 - 1.0) / n * dn_dVd; double dT2_dVb = -dT2_dVg * (dVth_dVb - 2.0 * t->vtm * ExpArg * dn_dVb) + (T2 - 1.0) / n * dn_dVb; d->vgst = T1 / T2; double T3 = T2 * T2; dVgsteff_dVg = (T2 * dT1_dVg - T1 * dT2_dVg) / T3 * dVgs_eff_dVg; dVgsteff_dVd = (T2 * dT1_dVd - T1 * dT2_dVd) / T3; dVgsteff_dVb = (T2 * dT1_dVb - T1 * dT2_dVb) / T3; trace4("<", d->vgst, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb); } Vgst2Vtm = d->vgst + 2.0 * t->vtm; trace3("", d->vgst, t->vtm, Vgst2Vtm); } trace1("", d->vgst); trace4("", dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb, Vgst2Vtm); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Calculate Effective Channel Geometry */ double Weff, dWeff_dVg, dWeff_dVb; { double T9 = sqrtPhis - t->sqrtPhi; Weff = s->weff - 2.0 * (s->dwg * d->vgst + s->dwb * T9); dWeff_dVg = -2.0 * s->dwg; dWeff_dVb = -2.0 * s->dwb * dsqrtPhis_dVb; if (Weff < 2.0e-8) { /* to avoid the discontinuity problem due to Weff*/ double T0 = 1.0 / (6.0e-8 - 2.0 * Weff); Weff = 2.0e-8 * (4.0e-8 - Weff) * T0; T0 *= T0 * 4.0e-16; dWeff_dVg *= T0; dWeff_dVb *= T0; trace3("Weff fix", Weff, dWeff_dVg, dWeff_dVb); } } trace3("", Weff, dWeff_dVg, dWeff_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double Rds, dRds_dVg, dRds_dVb; { double T9 = sqrtPhis - t->sqrtPhi; double T0 = s->prwg * d->vgst + s->prwb * T9; if (T0 >= -0.9) { Rds = t->rds0 * (1.0 + T0); dRds_dVg = t->rds0 * s->prwg; dRds_dVb = t->rds0 * s->prwb * dsqrtPhis_dVb; }else{ /* to avoid the discontinuity problem due to prwg and prwb*/ double T1 = 1.0 / (17.0 + 20.0 * T0); Rds = t->rds0 * (0.8 + T0) * T1; T1 *= T1; dRds_dVg = t->rds0 * s->prwg * T1; dRds_dVb = t->rds0 * s->prwb * dsqrtPhis_dVb * T1; trace3("Rds fix", T9, T0, T1); trace3("Rds fix", Rds, dRds_dVg, dRds_dVb); } } trace3("", Rds, dRds_dVg, dRds_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Calculate Abulk */ double Abulk0, dAbulk0_dVb, dAbulk_dVg, Abulk, dAbulk_dVb; { double T1 = 0.5 * t->k1 / sqrtPhis; double dT1_dVb = -T1 / sqrtPhis * dsqrtPhis_dVb; double T9 = sqrt(s->xj * Xdep); double tmp1 = s->leff + 2.0 * T9; double T5 = s->leff / tmp1; double tmp2 = s->a0 * T5; double tmp3 = s->weff + s->b1; double tmp4 = s->b0 / tmp3; double T2 = tmp2 + tmp4; double dT2_dVb = -T9 / tmp1 / Xdep * dXdep_dVb; double T6 = T5 * T5; double T7 = T5 * T6; Abulk0 = 1.0 + T1 * T2; dAbulk0_dVb = T1 * tmp2 * dT2_dVb + T2 * dT1_dVb; double T8 = s->ags * s->a0 * T7; dAbulk_dVg = -T1 * T8; Abulk = Abulk0 + dAbulk_dVg * d->vgst; dAbulk_dVb = dAbulk0_dVb - T8 * d->vgst * (dT1_dVb + 3.0 * T1 * dT2_dVb); trace2("1", Abulk0, dAbulk0_dVb); trace3("1", dAbulk_dVg, Abulk, dAbulk_dVb); if (Abulk0 < 0.1) { /* added to avoid the problems caused by Abulk0 */ double t9 = 1.0 / (3.0 - 20.0 * Abulk0); Abulk0 = (0.2 - Abulk0) * t9; dAbulk0_dVb *= t9 * t9; trace2("2", Abulk0, dAbulk0_dVb); } if (Abulk < 0.1) { /* added to avoid the problems caused by Abulk */ double t9 = 1.0 / (3.0 - 20.0 * Abulk); Abulk = (0.2 - Abulk) * t9; dAbulk_dVb *= t9 * t9; trace3("2", dAbulk_dVg, Abulk, dAbulk_dVb); } double T0, dT0_dVb; { double t2 = s->keta * Vbseff; if (t2 >= -0.9) { T0 = 1.0 / (1.0 + t2); dT0_dVb = -s->keta * T0 * T0; trace3("", t2, T0, dT0_dVb); }else{ /* added to avoid the problems caused by Keta */ double t1 = 1.0 / (0.8 + T2); T0 = (17.0 + 20.0 * T2) * t1; dT0_dVb = -s->keta * t1 * t1; trace3("keta fix", T2, T0, dT0_dVb); } } dAbulk_dVg *= T0; dAbulk_dVb = dAbulk_dVb * T0 + Abulk * dT0_dVb; dAbulk0_dVb = dAbulk0_dVb * T0 + Abulk0 * dT0_dVb; Abulk *= T0; Abulk0 *= T0; } trace2("", Abulk0, dAbulk0_dVb); trace3("", dAbulk_dVg, Abulk, dAbulk_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Mobility calculation */ double ueff, dueff_dVg, dueff_dVd, dueff_dVb; { double Denomi, dDenomi_dVg, dDenomi_dVd, dDenomi_dVb; { double T5; if (m->mobMod == 1) { double T0 = d->vgst + d->von + d->von; double T2 = t->ua + t->uc * Vbseff; double T3 = T0 / m->tox; T5 = T3 * (T2 + t->ub * T3); dDenomi_dVg = (T2 + 2.0 * t->ub * T3) / m->tox; dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + t->uc * T3; }else if (m->mobMod == 2) { T5 = d->vgst / m->tox * (t->ua + t->uc * Vbseff + t->ub * d->vgst / m->tox); dDenomi_dVg = (t->ua + t->uc * Vbseff + 2.0 * t->ub * d->vgst / m->tox) / m->tox; dDenomi_dVd = 0.0; dDenomi_dVb = d->vgst * t->uc / m->tox; }else{ double T0 = d->vgst + d->von + d->von; double T2 = 1.0 + t->uc * Vbseff; double T3 = T0 / m->tox; double T4 = T3 * (t->ua + t->ub * T3); T5 = T4 * T2; dDenomi_dVg = (t->ua + 2.0 * t->ub * T3) * T2 / m->tox; dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + t->uc * T4; } if (T5 >= -0.8) { Denomi = 1.0 + T5; }else{ /* Added to avoid the discontinuity problem caused by ua and ub*/ double t9 = 1.0 / (7.0 + 10.0 * T5); Denomi = (0.6 + T5) * t9; t9 *= t9; dDenomi_dVg *= t9; dDenomi_dVd *= t9; dDenomi_dVb *= t9; } } ueff = t->u0temp / Denomi; double t9 = -ueff / Denomi; dueff_dVg = t9 * dDenomi_dVg; dueff_dVd = t9 * dDenomi_dVd; dueff_dVb = t9 * dDenomi_dVb; } trace4("", ueff, dueff_dVg, dueff_dVd, dueff_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double Esat, EsatL, dEsatL_dVg, dEsatL_dVd, dEsatL_dVb; { Esat = 2.0 * t->vsattemp / ueff; EsatL = Esat * s->leff; double T0 = -EsatL /ueff; dEsatL_dVg = T0 * dueff_dVg; dEsatL_dVd = T0 * dueff_dVd; dEsatL_dVb = T0 * dueff_dVb; } trace2("", Esat, EsatL); trace3("", dEsatL_dVg, dEsatL_dVd, dEsatL_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double Vdsat, dVdsat_dVg, dVdsat_dVd, dVdsat_dVb; // d->vdsat double Vasat, dVasat_dVg, dVasat_dVb, dVasat_dVd; { double WVCoxRds; { double WVCox = Weff * t->vsattemp * m->cox; WVCoxRds = WVCox * Rds; } trace1("", WVCoxRds); double Lambda, dLambda_dVg; { if (s->a1 == 0.0) { Lambda = s->a2; dLambda_dVg = 0.0; }else if (s->a1 > 0.0) { /* avoid discontinuity problem caused by s->a1 and s->a2 (Lambda) */ double T0 = 1.0 - s->a2; double T1 = T0 - s->a1 * d->vgst - 0.0001; double T2 = sqrt(T1 * T1 + 0.0004 * T0); Lambda = s->a2 + T0 - 0.5 * (T1 + T2); dLambda_dVg = 0.5 * s->a1 * (1.0 + T1 / T2); }else{ double T1 = s->a2 + s->a1 * d->vgst - 0.0001; double T2 = sqrt(T1 * T1 + 0.0004 * s->a2); Lambda = 0.5 * (T1 + T2); dLambda_dVg = 0.5 * s->a1 * (1.0 + T1 / T2); } } trace2("", Lambda, dLambda_dVg); double tmp2, tmp3; if (Rds > 0) { tmp2 = dRds_dVg / Rds + dWeff_dVg / Weff; tmp3 = dRds_dVb / Rds + dWeff_dVb / Weff; }else{ tmp2 = dWeff_dVg / Weff; tmp3 = dWeff_dVb / Weff; } trace2("", tmp2, tmp3); //double Vdsat, dVdsat_dVg, dVdsat_dVd, dVdsat_dVb; // d->vdsat double tmp1; { if ((Rds == 0.0) && (Lambda == 1.0)) { double T0 = 1.0 / (Abulk * EsatL + Vgst2Vtm); tmp1 = 0.0; double T1 = T0 * T0; double T2 = Vgst2Vtm * T0; double T3 = EsatL * Vgst2Vtm; Vdsat = T3 * T0; double dT0_dVg = -(Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 1.0)*T1; double dT0_dVd = -(Abulk * dEsatL_dVd) * T1; double dT0_dVb = -(Abulk * dEsatL_dVb + dAbulk_dVb * EsatL) * T1; dVdsat_dVg = T3 * dT0_dVg + T2 * dEsatL_dVg + EsatL * T0; dVdsat_dVd = T3 * dT0_dVd + T2 * dEsatL_dVd; dVdsat_dVb = T3 * dT0_dVb + T2 * dEsatL_dVb; }else{ tmp1 = dLambda_dVg / (Lambda * Lambda); double T9 = Abulk * WVCoxRds; double T8 = Abulk * T9; double T7 = Vgst2Vtm * T9; double T6 = Vgst2Vtm * WVCoxRds; double T0 = 2.0 * Abulk * (T9 - 1.0 + 1.0 / Lambda); double dT0_dVg = 2.0 * (T8 * tmp2 - Abulk * tmp1 + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbulk_dVg); double dT0_dVb = 2.0 * (T8 * (2.0 / Abulk * dAbulk_dVb + tmp3) + (1.0 / Lambda - 1.0) * dAbulk_dVb); //double dT0_dVd = 0.0; double T1 = Vgst2Vtm * (2.0 / Lambda - 1.0) + Abulk * EsatL + 3.0*T7; double dT1_dVg = (2.0 / Lambda - 1.0) - 2.0 * Vgst2Vtm * tmp1 + Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 3.0 * (T9 + T7 * tmp2 + T6 * dAbulk_dVg); double dT1_dVb = Abulk * dEsatL_dVb + EsatL * dAbulk_dVb + 3.0 * (T6 * dAbulk_dVb + T7 * tmp3); double dT1_dVd = Abulk * dEsatL_dVd; double T2 = Vgst2Vtm * (EsatL + 2.0 * T6); double dT2_dVg = EsatL + Vgst2Vtm * dEsatL_dVg + T6 * (4.0 + 2.0 * Vgst2Vtm * tmp2); double dT2_dVb = Vgst2Vtm * (dEsatL_dVb + 2.0 * T6 * tmp3); double dT2_dVd = Vgst2Vtm * dEsatL_dVd; double T3 = sqrt(T1 * T1 - 2.0 * T0 * T2); Vdsat = (T1 - T3) / T0; dVdsat_dVg = (dT1_dVg - (T1 * dT1_dVg - dT0_dVg * T2 - T0 * dT2_dVg) / T3 - Vdsat * dT0_dVg) / T0; dVdsat_dVb = (dT1_dVb - (T1 * dT1_dVb - dT0_dVb * T2 - T0 * dT2_dVb) / T3 - Vdsat * dT0_dVb) / T0; dVdsat_dVd = (dT1_dVd - (T1 * dT1_dVd - T0 * dT2_dVd) / T3) / T0; } d->vdsat = Vdsat; d->saturated = (d->vds >= d->vdsat); } trace1("", tmp1); trace4("d->vdsat", Vdsat, dVdsat_dVg, dVdsat_dVd, dVdsat_dVb); // double Vasat, dVasat_dVg, dVasat_dVb, dVasat_dVd; { double tmp4 = 1.0 - 0.5 * Abulk * Vdsat / Vgst2Vtm; double T9 = WVCoxRds * d->vgst; double T8 = T9 / Vgst2Vtm; double T0 = EsatL + Vdsat + 2.0 * T9 * tmp4; double T7 = 2.0 * WVCoxRds * tmp4; double dT0_dVg = dEsatL_dVg + dVdsat_dVg + T7 * (1.0 + tmp2 * d->vgst) - T8 * (Abulk * dVdsat_dVg - Abulk * Vdsat / Vgst2Vtm + Vdsat * dAbulk_dVg); double dT0_dVb = dEsatL_dVb + dVdsat_dVb + T7 * tmp3 * d->vgst - T8 * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb); double dT0_dVd = dEsatL_dVd + dVdsat_dVd - T8 * Abulk * dVdsat_dVd; T9 = WVCoxRds * Abulk; double T1 = 2.0 / Lambda - 1.0 + T9; double dT1_dVg = -2.0 * tmp1 + WVCoxRds * (Abulk * tmp2 + dAbulk_dVg); double dT1_dVb = dAbulk_dVb * WVCoxRds + T9 * tmp3; Vasat = T0 / T1; dVasat_dVg = (dT0_dVg - Vasat * dT1_dVg) / T1; dVasat_dVb = (dT0_dVb - Vasat * dT1_dVb) / T1; dVasat_dVd = dT0_dVd / T1; } trace4("", Vasat, dVasat_dVg, dVasat_dVb, dVasat_dVd); } trace1("", d->vdsat); trace4("", Vdsat, dVdsat_dVg, dVdsat_dVd, dVdsat_dVb); trace4("", Vasat, dVasat_dVg, dVasat_dVb, dVasat_dVd); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Effective Vds (Vdseff) Calculation */ double Vdseff, diffVds, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb; { double T1 = Vdsat - d->vds - s->delta; double dT1_dVg = dVdsat_dVg; double dT1_dVd = dVdsat_dVd - 1.0; double dT1_dVb = dVdsat_dVb; trace4("", T1, dT1_dVg, dT1_dVd, dT1_dVb); double T2 = sqrt(T1 * T1 + 4.0 * s->delta * Vdsat); double T0 = T1 / T2; double T3 = 2.0 * s->delta / T2; trace3("", T2, T0, T3); double dT2_dVg = T0 * dT1_dVg + T3 * dVdsat_dVg; double dT2_dVd = T0 * dT1_dVd + T3 * dVdsat_dVd; double dT2_dVb = T0 * dT1_dVb + T3 * dVdsat_dVb; trace3("", dT2_dVg, dT2_dVd, dT2_dVb); Vdseff = Vdsat - 0.5 * (T1 + T2); dVdseff_dVg = dVdsat_dVg - 0.5 * (dT1_dVg + dT2_dVg); dVdseff_dVd = dVdsat_dVd - 0.5 * (dT1_dVd + dT2_dVd); dVdseff_dVb = dVdsat_dVb - 0.5 * (dT1_dVb + dT2_dVb); trace4("raw", Vdseff, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb); fixzero(&Vdseff, Vdsat); fixzero(&dVdseff_dVg, dVdsat_dVg); fixzero(&dVdseff_dVd, dVdsat_dVd); fixzero(&dVdseff_dVb, dVdsat_dVb); /* Added to eliminate non-zero Vdseff at Vds=0.0 */ if (d->vds == 0.0) { assert(Vdseff == 0.0); assert(dVdseff_dVg == 0.0); assert(dVdseff_dVb == 0.0); } if (Vdseff > d->vds) { // From Spice, to fix numeric problems. trace2("numeric problems", Vdseff, d->vds); Vdseff = d->vds; } trace4("fixed", Vdseff, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb); diffVds = d->vds - Vdseff; trace2("", Vdseff, diffVds); } trace2("", Vdseff, diffVds); trace3("", dVdseff_dVg, dVdseff_dVd, dVdseff_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Calculate Ids */ double Idsa, dIdsa_dVg, dIdsa_dVd, dIdsa_dVb; { double Va, dVa_dVg, dVa_dVd, dVa_dVb; { double VACLM, dVACLM_dVg, dVACLM_dVb, dVACLM_dVd; if ((s->pclm > 0.0) && (diffVds > 1.0e-10)) { double T0 = 1.0 / (s->pclm * Abulk * s->litl); double dT0_dVb = -T0 / Abulk * dAbulk_dVb; double dT0_dVg = -T0 / Abulk * dAbulk_dVg; double T2 = d->vgst / EsatL; double T1 = s->leff * (Abulk + T2); double dT1_dVg = s->leff * ((1.0-T2*dEsatL_dVg)/EsatL + dAbulk_dVg); double dT1_dVb = s->leff * (dAbulk_dVb - T2 * dEsatL_dVb / EsatL); double dT1_dVd = -T2 * dEsatL_dVd / Esat; double T9 = T0 * T1; VACLM = T9 * diffVds; dVACLM_dVg = T0 * dT1_dVg * diffVds - T9 * dVdseff_dVg + T1 * diffVds * dT0_dVg; dVACLM_dVb = (dT0_dVb*T1 + T0*dT1_dVb) * diffVds - T9 * dVdseff_dVb; dVACLM_dVd = T0 * dT1_dVd * diffVds + T9 * (1.0 - dVdseff_dVd); }else{ VACLM = MAX_EXP; dVACLM_dVd = dVACLM_dVg = dVACLM_dVb = 0.0; } trace4("", VACLM, dVACLM_dVg, dVACLM_dVb, dVACLM_dVd); double VADIBL, dVADIBL_dVg, dVADIBL_dVb, dVADIBL_dVd; if (t->thetaRout > 0.0) { double T8 = Abulk * Vdsat; double T0 = Vgst2Vtm * T8; double dT0_dVg = Vgst2Vtm * Abulk * dVdsat_dVg + T8 + Vgst2Vtm * Vdsat * dAbulk_dVg; double dT0_dVb = Vgst2Vtm * (dAbulk_dVb*Vdsat + Abulk*dVdsat_dVb); double dT0_dVd = Vgst2Vtm * Abulk * dVdsat_dVd; double T1 = Vgst2Vtm + T8; double dT1_dVg = 1.0 + Abulk * dVdsat_dVg + Vdsat * dAbulk_dVg; double dT1_dVb = Abulk * dVdsat_dVb + dAbulk_dVb * Vdsat; double dT1_dVd = Abulk * dVdsat_dVd; double T9 = T1 * T1; double T2 = t->thetaRout; VADIBL = (Vgst2Vtm - T0 / T1) / T2; dVADIBL_dVg = (1.0 - dT0_dVg / T1 + T0 * dT1_dVg / T9) / T2; dVADIBL_dVb = (-dT0_dVb / T1 + T0 * dT1_dVb / T9) / T2; dVADIBL_dVd = (-dT0_dVd / T1 + T0 * dT1_dVd / T9) / T2; double T7 = s->pdiblb * Vbseff; if (T7 >= -0.9) { double T3 = 1.0 / (1.0 + T7); VADIBL *= T3; dVADIBL_dVg *= T3; dVADIBL_dVb = (dVADIBL_dVb - VADIBL * s->pdiblb) * T3; dVADIBL_dVd *= T3; }else{ /* Added to avoid the discontinuity problem caused by pdiblcb */ double T4 = 1.0 / (0.8 + T7); double T3 = (17.0 + 20.0 * T7) * T4; dVADIBL_dVg *= T3; dVADIBL_dVb = dVADIBL_dVb * T3 - VADIBL * s->pdiblb * T4 * T4; dVADIBL_dVd *= T3; VADIBL *= T3; } }else{ VADIBL = MAX_EXP; dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = 0.0; } trace4("", VADIBL, dVADIBL_dVg, dVADIBL_dVb, dVADIBL_dVd); double T8 = s->pvag / EsatL; double T9 = T8 * d->vgst; double T0, dT0_dVg, dT0_dVb, dT0_dVd; if (T9 > -0.9) { T0 = 1.0 + T9; dT0_dVg = T8 * (1.0 - d->vgst * dEsatL_dVg / EsatL); dT0_dVb = -T9 * dEsatL_dVb / EsatL; dT0_dVd = -T9 * dEsatL_dVd / EsatL; }else{ /* Added to avoid the discontinuity problems caused by pvag */ double T1 = 1.0 / (17.0 + 20.0 * T9); T0 = (0.8 + T9) * T1; T1 *= T1; dT0_dVg = T8 * (1.0 - d->vgst * dEsatL_dVg / EsatL) * T1; T9 *= T1 / EsatL; dT0_dVb = -T9 * dEsatL_dVb; dT0_dVd = -T9 * dEsatL_dVd; } double tmp1 = VACLM * VACLM; double tmp2 = VADIBL * VADIBL; double tmp3 = VACLM + VADIBL; double T1 = VACLM * VADIBL / tmp3; tmp3 *= tmp3; double dT1_dVg = (tmp1 * dVADIBL_dVg + tmp2 * dVACLM_dVg) / tmp3; double dT1_dVd = (tmp1 * dVADIBL_dVd + tmp2 * dVACLM_dVd) / tmp3; double dT1_dVb = (tmp1 * dVADIBL_dVb + tmp2 * dVACLM_dVb) / tmp3; Va = Vasat + T0 * T1; dVa_dVg = dVasat_dVg + T1 * dT0_dVg + T0 * dT1_dVg; dVa_dVd = dVasat_dVd + T1 * dT0_dVd + T0 * dT1_dVd; dVa_dVb = dVasat_dVb + T1 * dT0_dVb + T0 * dT1_dVb; } trace4("", Va, dVa_dVg, dVa_dVd, dVa_dVb); double Idl, dIdl_dVg, dIdl_dVd, dIdl_dVb; { double gche, dgche_dVg, dgche_dVd, dgche_dVb; { double beta, dbeta_dVg, dbeta_dVd, dbeta_dVb; { double CoxWovL = m->cox * Weff / s->leff; beta = ueff * CoxWovL; dbeta_dVg = CoxWovL * dueff_dVg + beta * dWeff_dVg / Weff; dbeta_dVd = CoxWovL * dueff_dVd; dbeta_dVb = CoxWovL * dueff_dVb + beta * dWeff_dVb / Weff; } trace4("", beta, dbeta_dVg, dbeta_dVd, dbeta_dVb); double fgche1, dfgche1_dVg, dfgche1_dVd, dfgche1_dVb; { double T0 = 1.0 - 0.5 * Abulk * Vdseff / Vgst2Vtm; double dT0_dVg = -0.5 * (Abulk * dVdseff_dVg - Abulk * Vdseff / Vgst2Vtm + Vdseff * dAbulk_dVg) / Vgst2Vtm; double dT0_dVd = -0.5 * Abulk * dVdseff_dVd / Vgst2Vtm; double dT0_dVb = -0.5 * (Abulk*dVdseff_dVb + dAbulk_dVb*Vdseff) / Vgst2Vtm; fgche1 = d->vgst * T0; dfgche1_dVg = d->vgst * dT0_dVg + T0; dfgche1_dVd = d->vgst * dT0_dVd; dfgche1_dVb = d->vgst * dT0_dVb; } trace4("", fgche1, dfgche1_dVg, dfgche1_dVd, dfgche1_dVb); double fgche2, dfgche2_dVg, dfgche2_dVd, dfgche2_dVb; { double T9 = Vdseff / EsatL; fgche2 = 1.0 + T9; dfgche2_dVg = (dVdseff_dVg - T9 * dEsatL_dVg) / EsatL; dfgche2_dVd = (dVdseff_dVd - T9 * dEsatL_dVd) / EsatL; dfgche2_dVb = (dVdseff_dVb - T9 * dEsatL_dVb) / EsatL; } trace4("", fgche2, dfgche2_dVg, dfgche2_dVd, dfgche2_dVb); gche = beta * fgche1 / fgche2; dgche_dVg = (beta * dfgche1_dVg + fgche1 * dbeta_dVg - gche * dfgche2_dVg) / fgche2; dgche_dVd = (beta * dfgche1_dVd + fgche1 * dbeta_dVd - gche * dfgche2_dVd) / fgche2; dgche_dVb = (beta * dfgche1_dVb + fgche1 * dbeta_dVb - gche * dfgche2_dVb) / fgche2; } trace4("", gche, dgche_dVg, dgche_dVd, dgche_dVb); double T0 = 1.0 + gche * Rds; double T9 = Vdseff / T0; Idl = gche * T9; dIdl_dVg = (gche * dVdseff_dVg + T9 * dgche_dVg) / T0 - Idl * gche / T0 * dRds_dVg; dIdl_dVd = (gche * dVdseff_dVd + T9 * dgche_dVd) / T0; dIdl_dVb = (gche*dVdseff_dVb + T9*dgche_dVb - Idl*dRds_dVb*gche) / T0; } trace4("", Idl, dIdl_dVg, dIdl_dVd, dIdl_dVb); double T9 = diffVds / Va; double T0 = 1.0 + T9; Idsa = Idl * T0; dIdsa_dVg = T0 * dIdl_dVg - Idl * (dVdseff_dVg + T9 * dVa_dVg) / Va; dIdsa_dVd = T0 * dIdl_dVd + Idl * (1.0 - dVdseff_dVd - T9*dVa_dVd) / Va; dIdsa_dVb = T0 * dIdl_dVb - Idl * (dVdseff_dVb + T9 * dVa_dVb) / Va; } trace4("", Idsa, dIdsa_dVg, dIdsa_dVd, dIdsa_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // d->ids, d->gds, d->gmf, d->gmbf { double VASCBE, dVASCBE_dVg, dVASCBE_dVd, dVASCBE_dVb; if (s->pscbe2 > 0.0) { if (diffVds > s->pscbe1 * s->litl / EXP_THRESHOLD) { double T0 = s->pscbe1 * s->litl / diffVds; VASCBE = s->leff * exp(T0) / s->pscbe2; double T1 = T0 * VASCBE / diffVds; dVASCBE_dVg = T1 * dVdseff_dVg; dVASCBE_dVd = -T1 * (1.0 - dVdseff_dVd); dVASCBE_dVb = T1 * dVdseff_dVb; }else{ VASCBE = MAX_EXP * s->leff/s->pscbe2; dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0; } }else{ VASCBE = MAX_EXP; dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0; } double T9 = diffVds / VASCBE; double T0 = 1.0 + T9; double Ids = Idsa * T0; double Gm = T0*dIdsa_dVg - Idsa*(dVdseff_dVg + T9*dVASCBE_dVg) / VASCBE; double Gds = T0 * dIdsa_dVd + Idsa * (1.0 - dVdseff_dVd - T9 * dVASCBE_dVd) / VASCBE; double Gmb = T0 * dIdsa_dVb - Idsa * (dVdseff_dVb + T9 * dVASCBE_dVb) / VASCBE; trace3("", T0, dIdsa_dVb, (T0 * dIdsa_dVb)); trace4("", dVdseff_dVb, T9, dVASCBE_dVb, (dVdseff_dVb + T9*dVASCBE_dVb)); trace3("", Idsa, VASCBE, (Idsa*(dVdseff_dVb+T9*dVASCBE_dVb)/VASCBE)); Gds += Gm * dVgsteff_dVd; Gmb += Gm * dVgsteff_dVb; Gm *= dVgsteff_dVg; Gmb *= dVbseff_dVb; trace4("", Ids, Gm, Gds, Gmb); trace0("========================="); d->gds = Gds; if (d->reversed) { d->ids = -Ids; d->gmr = Gm; d->gmbr = Gmb; d->gmf = d->gmbf = 0; }else{ d->ids = Ids; d->gmf = Gm; d->gmbf = Gmb; d->gmr = d->gmbr = 0.; } } trace4("", d->ids, d->gds, d->gmf, d->gmbf); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // d->isub, d->gbbs, d->gbgs, d->gbds { /* calculate substrate current Isub */ double Isub, Gbd, Gbb, Gbg; if ((s->alpha0 <= 0.0) || (s->beta0 <= 0.0)) { Isub = Gbd = Gbb = Gbg = 0.0; trace4("no-isub", Isub, Gbd, Gbb, Gbg); }else{ double T2 = s->alpha0 / s->leff; double T1, dT1_dVg, dT1_dVd, dT1_dVb; if (diffVds > s->beta0 / EXP_THRESHOLD) { double T0 = -s->beta0 / diffVds; T1 = T2 * diffVds * exp(T0); double T3 = T1 / diffVds * (T0 - 1.0); trace3("", T0, T2, T3); dT1_dVg = T3 * dVdseff_dVg; dT1_dVd = T3 * (dVdseff_dVd - 1.0); dT1_dVb = T3 * dVdseff_dVb; trace4("vds > ?", T1, dT1_dVg, dT1_dVd, dT1_dVb); }else{ double T3 = T2 * MIN_EXP; trace2("", T2, T3); T1 = T3 * diffVds; dT1_dVg = -T3 * dVdseff_dVg; dT1_dVd = T3 * (1.0 - dVdseff_dVd); dT1_dVb = -T3 * dVdseff_dVb; trace4("vds < ?", T1, dT1_dVg, dT1_dVd, dT1_dVb); } Isub = T1 * Idsa; Gbg = T1 * dIdsa_dVg + Idsa * dT1_dVg; Gbd = T1 * dIdsa_dVd + Idsa * dT1_dVd; Gbb = T1 * dIdsa_dVb + Idsa * dT1_dVb; trace4("raw", Isub, Gbd, Gbb, Gbg); Gbd += Gbg * dVgsteff_dVd; Gbb += Gbg * dVgsteff_dVb; Gbg *= dVgsteff_dVg; Gbb *= dVbseff_dVb; /* bug fixing */ } trace4("", Isub, Gbd, Gbb, Gbg); if (d->reversed) { d->idb = Isub; d->gdbds = Gbd; d->gdbgs = Gbg; d->gdbbs = Gbb; d->isb = d->gsbsd = d->gsbgd = d->gsbbd = 0.; }else{ d->idb = d->gdbds = d->gdbgs = d->gdbbs = 0.; d->isb = Isub; d->gsbsd = Gbd; d->gsbgd = Gbg; d->gsbbd = Gbb; } //double d__csub = Isub - (Gbb * Vbseff + Gbd * d->vds + Gbg * d->vgs); } trace4("", d->isub, d->gbbs, d->gbgs, d->gbds); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Calculate Qinv for Noise analysis */ { //double T1 = d->vgst * (1.0 - 0.5 * Abulk * Vdseff / Vgst2Vtm); //double d__qinv = -m->cox * Weff * s->leff * T1; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ends line 2020 (finished) // d->qgate, d->qdrn, d->qbulk // d->cggb, d->cgsb, d->cgdb // d->cdgb, d->cdsb, d->cddb // d->cbgb, d->cbsb, d->cbdb { const bool ChargeComputationNeeded = true; trace2("", m->xpart, m->capMod); if ((m->xpart < 0) || (!ChargeComputationNeeded)) { d->qgate = d->qdrn = d->qbulk = 0.0; d->cggb = d->cgsb = d->cgdb = 0.0; d->cdgb = d->cdsb = d->cddb = 0.0; d->cbgb = d->cbsb = d->cbdb = 0.0; trace0("xpart < 0 || no charge computation"); }else if (m->capMod == 0) { // block ends 1710 this 1454 trace0("begin capMod == 0 (mos7)"); if (Vbseff < 0.0) { // redefinition Vbseff = d->vbs; dVbseff_dVb = 1.0; }else{ Vbseff = t->phi - Phis; dVbseff_dVb = -dPhis_dVb; } trace1("old value replaced", dVth_dVb); double Vfb = s->vfbcv; // possible improper redefinition later double Vth = Vfb + t->phi + t->k1 * sqrtPhis; dVth_dVb = t->k1 * dsqrtPhis_dVb; // redefinition double Vgst = Vgs_eff - Vth; //double dVgst_dVb = -dVth_dVb; //double dVgst_dVg = dVgs_eff_dVg; double CoxWL = m->cox * s->weffCV * s->leffCV; double Arg1 = Vgs_eff - Vbseff - Vfb; trace3("", Vfb, Vth, dVth_dVb); trace3("", Vgst, CoxWL, Arg1); // ends 1618 this 1328 if (Arg1 <= 0.0) { trace0("Arg1 <= 0.0"); d->qgate = CoxWL * Arg1; d->cggb = CoxWL * dVgs_eff_dVg; d->cgdb = 0.0; d->cgsb = CoxWL * (dVbseff_dVb - dVgs_eff_dVg); d->qbulk = -d->qgate; d->cbgb = -CoxWL * dVgs_eff_dVg; d->cbdb = 0.0; d->cbsb = -d->cgsb; d->qdrn = 0.0; d->cdgb = 0.0; d->cddb = 0.0; d->cdsb = 0.0; }else if (Vgst <= 0.0) { trace0("Vgst <= 0.0"); double T1 = 0.5 * t->k1; double T2 = sqrt(T1 * T1 + Arg1); double T0 = CoxWL * T1 / T2; d->qgate = CoxWL * t->k1 * (T2 - T1); d->cggb = T0 * dVgs_eff_dVg; d->cgdb = 0.0; d->cgsb = T0 * (dVbseff_dVb - dVgs_eff_dVg); d->qbulk = -d->qgate; d->cbgb = -d->cggb; d->cbdb = 0.0; d->cbsb = -d->cgsb; d->qdrn = 0.0; d->cdgb = 0.0; d->cddb = 0.0; d->cdsb = 0.0; }else{ trace0("!(Arg1 <= 0.0 || Vgst <= 0.0)"); double One_Third_CoxWL = CoxWL / 3.0; double Two_Third_CoxWL = 2.0 * One_Third_CoxWL; // redefine Vdsat, dVdsat_dVg, dVdsat_dVb { double AbulkCV = Abulk0 * s->abulkCVfactor; double dAbulkCV_dVb = s->abulkCVfactor * dAbulk0_dVb; Vdsat = Vgst / AbulkCV; dVdsat_dVg = dVgs_eff_dVg / AbulkCV; dVdsat_dVb = - (Vdsat * dAbulkCV_dVb + dVth_dVb)/ AbulkCV; } if (m->xpart > 0.5) { /* 0/100 Charge petition model */ if (d->vds >= Vdsat) { /* saturation region */ double T1 = Vdsat / 3.0; double T2 = -One_Third_CoxWL * dVdsat_dVb; d->qgate = CoxWL * (Vgs_eff - Vfb - t->phi - T1); d->cggb = One_Third_CoxWL * (3.0 - dVdsat_dVg) * dVgs_eff_dVg; d->cgsb = -(d->cggb + T2); d->cgdb = 0.0; double T2a = -Two_Third_CoxWL * Vgst; double T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); d->qbulk = -(d->qgate + T2a); d->cbgb = -(d->cggb - Two_Third_CoxWL * dVgs_eff_dVg); d->cbsb = -(d->cbgb + T3); d->cbdb = 0.0; d->qdrn = 0.0; d->cdgb = 0.0; d->cddb = 0.0; d->cdsb = 0.0; }else{ /* linear region */ double Alphaz = Vgst / Vdsat; double T1 = 2.0 * Vdsat - d->vds; double T2 = d->vds / (3.0 * T1); double T3 = T2 * d->vds; double T9 = 0.25 * CoxWL; double T4 = T9 * Alphaz; double T7 = 2.0 * d->vds - T1 - 3.0 * T3; double T8 = T3 - T1 - 2.0 * d->vds; d->qgate = CoxWL * (Vgs_eff - Vfb - t->phi - 0.5 * (d->vds-T3)); double T10 = T4 * T8; d->qdrn = T4 * T7; d->qbulk = -(d->qgate + d->qdrn + T10); double T5 = T3 / T1; d->cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg; double T11 = -CoxWL * T5 * dVdsat_dVb; d->cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5); d->cgsb = -(d->cggb + T11 + d->cgdb); double T6 = 1.0 / Vdsat; double dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg); double dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb); T7 = T9 * T7; T8 = T9 * T8; T9 = 2.0 * T4 * (1.0 - 3.0 * T5); d->cdgb = (T7 * dAlphaz_dVg - T9 * dVdsat_dVg) * dVgs_eff_dVg; double T12 = T7 * dAlphaz_dVb - T9 * dVdsat_dVb; d->cddb = T4 * (3.0 - 6.0 * T2 - 3.0 * T5); d->cdsb = -(d->cdgb + T12 + d->cddb); T9 = 2.0 * T4 * (1.0 + T5); T10 = (T8 * dAlphaz_dVg - T9 * dVdsat_dVg) * dVgs_eff_dVg; T11 = T8 * dAlphaz_dVb - T9 * dVdsat_dVb; T12 = T4 * (2.0 * T2 + T5 - 1.0); double T0 = -(T10 + T11 + T12); d->cbgb = -(d->cggb + d->cdgb + T10); d->cbdb = -(d->cgdb + d->cddb + T12); d->cbsb = -(d->cgsb + d->cdsb + T0); } }else if (m->xpart < 0.5) { /* 40/60 Charge petition model */ if (d->vds >= Vdsat) { /* saturation region */ double T1 = Vdsat / 3.0; d->qgate = CoxWL * (Vgs_eff - Vfb - t->phi - T1); double T2 = -Two_Third_CoxWL * Vgst; d->qbulk = -(d->qgate + T2); d->qdrn = 0.4 * T2; d->cggb = One_Third_CoxWL * (3.0 - dVdsat_dVg) * dVgs_eff_dVg; T2 = -One_Third_CoxWL * dVdsat_dVb; d->cgsb = -(d->cggb + T2); d->cgdb = 0.0; double T3 = 0.4 * Two_Third_CoxWL; d->cdgb = -T3 * dVgs_eff_dVg; d->cddb = 0.0; double T4 = T3 * dVth_dVb; d->cdsb = -(T4 + d->cdgb); d->cbgb = -(d->cggb - Two_Third_CoxWL * dVgs_eff_dVg); T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); d->cbsb = -(d->cbgb + T3); d->cbdb = 0.0; }else{ /* linear region */ double T1 = 2.0 * Vdsat - d->vds; double T2 = d->vds / (3.0 * T1); double T3 = T2 * d->vds; d->qgate = CoxWL * (Vgs_eff - Vfb - t->phi - 0.5 * (d->vds - T3)); double T5 = T3 / T1; d->cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg; double tmp = -CoxWL * T5 * dVdsat_dVb; d->cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5); d->cgsb = -(d->cggb + d->cgdb + tmp); double T6 = 1.0 / Vdsat; double Alphaz = T6 * Vgst; double dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg); double dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb); T6 = 8.0 * Vdsat * Vdsat - 6.0 * Vdsat * d->vds + 1.2 * d->vds * d->vds; double T8 = T2 / T1; double T7 = d->vds - T1 - T8 * T6; double T9 = 0.25 * CoxWL; double T4 = T9 * Alphaz; d->qdrn = T4 * T7; T7 *= T9; tmp = T8 / T1; double tmp1 = T4 * (2.0 - 4.0 * tmp * T6 + T8 * (16.0 * Vdsat - 6.0 * d->vds)); d->cdgb = (T7 * dAlphaz_dVg - tmp1 * dVdsat_dVg) * dVgs_eff_dVg; double T10 = T7 * dAlphaz_dVb - tmp1 * dVdsat_dVb; d->cddb = T4 * (2.0 - (1.0 / (3.0 * T1 * T1) + 2.0 * tmp) * T6 + T8 * (6.0 * Vdsat - 2.4 * d->vds)); d->cdsb = -(d->cdgb + T10 + d->cddb); T7 = 2.0 * (T1 + T3); d->qbulk = -(d->qgate - T4 * T7); T7 *= T9; double T0 = 4.0 * T4 * (1.0 - T5); double T12 = (-T7 * dAlphaz_dVg - d->cdgb - T0 * dVdsat_dVg) * dVgs_eff_dVg; double T11 = -T7 * dAlphaz_dVb - T10 - T0 * dVdsat_dVb; T10 = -4.0 * T4 * (T2 - 0.5 + 0.5 * T5) - d->cddb; tmp = -(T10 + T11 + T12); d->cbgb = -(d->cggb + d->cdgb + T12); d->cbdb = -(d->cgdb + d->cddb + T11); d->cbsb = -(d->cgsb + d->cdsb + tmp); trace3("0,40/60,lin", T10, T11, T12); trace3("0,40/60,lin", d->cbgb, d->cbdb, d->cbsb); } }else{ /* 50/50 partitioning */ if (d->vds >= Vdsat) { /* saturation region */ double T1 = Vdsat / 3.0; d->qgate = CoxWL * (Vgs_eff - Vfb - t->phi - T1); double T2 = -Two_Third_CoxWL * Vgst; d->qbulk = -(d->qgate + T2); d->qdrn = 0.5 * T2; T2 = -One_Third_CoxWL * dVdsat_dVb; d->cggb = One_Third_CoxWL * (3.0 - dVdsat_dVg) * dVgs_eff_dVg; d->cgsb = -(d->cggb + T2); d->cgdb = 0.0; double T4 = One_Third_CoxWL * dVth_dVb; d->cdgb = -One_Third_CoxWL * dVgs_eff_dVg; d->cddb = 0.0; d->cdsb = -(T4 + d->cdgb); double T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); d->cbgb = -(d->cggb - Two_Third_CoxWL * dVgs_eff_dVg); d->cbsb = -(d->cbgb + T3); d->cbdb = 0.0; }else{ /* linear region */ double T1 = 2.0 * Vdsat - d->vds; double T2 = d->vds / (3.0 * T1); double T3 = T2 * d->vds; double T5 = T3 / T1; double tmp = -CoxWL * T5 * dVdsat_dVb; d->qgate = CoxWL * (Vgs_eff - Vfb - t->phi - 0.5 * (d->vds-T3)); d->cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg; d->cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5); d->cgsb = -(d->cggb + d->cgdb + tmp); double T6 = 1.0 / Vdsat; double Alphaz = T6 * Vgst; double dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg); double dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb); double T9 = 0.25 * CoxWL; double T4 = T9 * Alphaz; double T7 = T1 + T3; d->qdrn = -T4 * T7; d->qbulk = - (d->qgate + d->qdrn + d->qdrn); T7 *= T9; double T0 = T4 * (2.0 * T5 - 2.0); double T12 = T0 * dVdsat_dVb - T7 * dAlphaz_dVb; d->cdgb = (T0 * dVdsat_dVg - T7 * dAlphaz_dVg) * dVgs_eff_dVg; d->cddb = T4 * (1.0 - 2.0 * T2 - T5); d->cdsb = -(d->cdgb + T12 + d->cddb); d->cbgb = -(d->cggb + 2.0 * d->cdgb); d->cbdb = -(d->cgdb + 2.0 * d->cddb); d->cbsb = -(d->cgsb + 2.0 * d->cdsb); } } } // begins 1328 this 1618 trace0("end capMod == 0"); // end of else if (m->capMod == 0) line 1454 this 1709 }else{ trace0("begin capMod != 0 (mos7)"); assert(m->capMod != 0); double qsrc; double VbseffCV, dVbseffCV_dVb; if (Vbseff < 0.0) { VbseffCV = Vbseff; dVbseffCV_dVb = 1.0; }else{ VbseffCV = t->phi - Phis; dVbseffCV_dVb = -dPhis_dVb; } trace2("", VbseffCV, dVbseffCV_dVb); //double Vth = d->von; // possibly wrong value -- scope problem double Vfb = d->von - t->phi - t->k1 * sqrtPhis; double dVfb_dVb = 0.;//////dVth_dVb - t->k1 * dsqrtPhis_dVb; double dVfb_dVd = 0.;//////dVth_dVd; //double Vgst = Vgs_eff - d->von; //trace3("", d->vgst, Vgst, VgstNVt); trace2("", n, t->vtm); double Vgsteff; { if ((VgstNVt > -EXP_THRESHOLD) && (VgstNVt < EXP_THRESHOLD)) { trace0("VgstNVt in range"); assert(ExpVgst != NOT_VALID); ExpVgst *= ExpVgst; ExpVgst = exp(VgstNVt); ////// test trace1("", ExpVgst); Vgsteff = n * t->vtm * log(1.0 + ExpVgst); dVgsteff_dVg = ExpVgst / (1.0 + ExpVgst); dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + (Vgs_eff - d->von) / n * dn_dVd) + Vgsteff / n * dn_dVd; dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + (Vgs_eff - d->von) / n * dn_dVb) + Vgsteff / n * dn_dVb; dVgsteff_dVg *= dVgs_eff_dVg; }else{ Vgsteff = d->vgst; } } trace4("", Vgsteff, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb); double CoxWL = m->cox * s->weffCV * s->leffCV; // redundant?? if (m->capMod == 1) { double Cgg, Cgd, Cgb; { double Arg1 = Vgs_eff - VbseffCV - Vfb - Vgsteff; if (Arg1 <= 0.0) { d->qgate = CoxWL * Arg1; Cgg = CoxWL * (dVgs_eff_dVg - dVgsteff_dVg); Cgd = -CoxWL * (dVfb_dVd + dVgsteff_dVd); Cgb = -CoxWL * (dVfb_dVb + dVbseffCV_dVb + dVgsteff_dVb); }else{ double T0 = 0.5 * t->k1; double T1 = sqrt(T0 * T0 + Arg1); double T2 = CoxWL * T0 / T1; d->qgate = CoxWL * t->k1 * (T1 - T0); Cgg = T2 * (dVgs_eff_dVg - dVgsteff_dVg); Cgd = -T2 * (dVfb_dVd + dVgsteff_dVd); Cgb = -T2 * (dVfb_dVb + dVbseffCV_dVb + dVgsteff_dVb); } } d->qbulk = -d->qgate; double Cbg = -Cgg; double Cbd = -Cgd; double Cbb = -Cgb; double AbulkCV = Abulk0 * s->abulkCVfactor; double dAbulkCV_dVb = s->abulkCVfactor * dAbulk0_dVb; double Csg, Csb, Csd; { double VdsatCV = Vgsteff / AbulkCV; if (VdsatCV < d->vds) { double One_Third_CoxWL = CoxWL / 3.0; double Two_Third_CoxWL = 2.0 * One_Third_CoxWL; double dVdsatCV_dVg = 1.0 / AbulkCV; double dVdsatCV_dVb = -VdsatCV * dAbulkCV_dVb / AbulkCV; { double T0 = Vgsteff - VdsatCV / 3.0; double dT0_dVg = 1.0 - dVdsatCV_dVg / 3.0; double dT0_dVb = -dVdsatCV_dVb / 3.0; d->qgate += CoxWL * T0; double Cgg1 = CoxWL * dT0_dVg; double Cgb1 = CoxWL * dT0_dVb + Cgg1 * dVgsteff_dVb; double Cgd1 = Cgg1 * dVgsteff_dVd; Cgg1 *= dVgsteff_dVg; Cgg += Cgg1; Cgb += Cgb1; Cgd += Cgd1; } { double T0 = VdsatCV - Vgsteff; double dT0_dVg = dVdsatCV_dVg - 1.0; double dT0_dVb = dVdsatCV_dVb; d->qbulk += One_Third_CoxWL * T0; double Cbg1 = One_Third_CoxWL * dT0_dVg; double Cbb1 = One_Third_CoxWL * dT0_dVb + Cbg1 * dVgsteff_dVb; double Cbd1 = Cbg1 * dVgsteff_dVd; Cbg1 *= dVgsteff_dVg; Cbg += Cbg1; Cbb += Cbb1; Cbd += Cbd1; } double T0; if (m->xpart > 0.5) { T0 = -Two_Third_CoxWL; }else if (m->xpart < 0.5) { T0 = -0.4 * CoxWL; }else{ T0 = -One_Third_CoxWL; } qsrc = T0 * Vgsteff; Csg = T0 * dVgsteff_dVg; Csb = T0 * dVgsteff_dVb; Csd = T0 * dVgsteff_dVd; Cgb *= dVbseff_dVb; Cbb *= dVbseff_dVb; Csb *= dVbseff_dVb; }else{ double T0 = AbulkCV * d->vds; double T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1.e-20); double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1; { double T2 = d->vds / T1; double T3 = T0 * T2; double dT3_dVg = -12.0 * T2 * T2 * AbulkCV; double dT3_dVd = 6.0 * T0 * (4.0*Vgsteff - T0) / T1 / T1 - 0.5; double dT3_dVb = 12.0 * T2 * T2 * dAbulkCV_dVb * Vgsteff; d->qgate += CoxWL * (Vgsteff - 0.5 * d->vds + T3); Cgg1 = CoxWL * (1.0 + dT3_dVg); Cgb1 = CoxWL * dT3_dVb + Cgg1 * dVgsteff_dVb; Cgd1 = CoxWL * dT3_dVd + Cgg1 * dVgsteff_dVd; Cgg1 *= dVgsteff_dVg; Cgg += Cgg1; Cgb += Cgb1; Cgd += Cgd1; d->qbulk += CoxWL * (1.0 - AbulkCV) * (0.5 * d->vds - T3); Cbg1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVg); Cbb1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVb + (0.5 * d->vds - T3) * dAbulkCV_dVb) + Cbg1 * dVgsteff_dVb; Cbd1 = -CoxWL * (1.0 - AbulkCV) * dT3_dVd + Cbg1 * dVgsteff_dVd; Cbg1 *= dVgsteff_dVg; Cbg += Cbg1; Cbb += Cbb1; Cbd += Cbd1; } if (m->xpart > 0.5) { /* 0/100 Charge petition model */ T1 = T1 + T1; qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 - T0 * T0 / T1); Csg = -CoxWL * (0.5 + 24.0 * T0 * d->vds / T1 / T1 * AbulkCV); Csb = -CoxWL * (0.25 * d->vds * dAbulkCV_dVb - 12.0 * T0 * d->vds / T1 / T1 * (4.0 * Vgsteff - T0) * dAbulkCV_dVb) + Csg * dVgsteff_dVb; Csd = -CoxWL * (0.25 * AbulkCV - 12.0 * AbulkCV * T0 / T1 / T1 * (4.0 * Vgsteff - T0)) + Csg * dVgsteff_dVd; Csg *= dVgsteff_dVg; }else if (m->xpart < 0.5) { /* 40/60 Charge petition model */ T1 = T1 / 12.0; double T2 = 0.5 * CoxWL / (T1 * T1); double T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff * (Vgsteff - 4.0 * T0 / 3.0)) - 2.0 * T0 * T0 * T0 / 15.0; qsrc = -T2 * T3; double T4 = 4.0 / 3.0 * Vgsteff * (Vgsteff-T0) + 0.4 * T0 * T0; Csg = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0 * Vgsteff - 8.0 * T0 / 3.0) + 2.0 * T0 * T0 / 3.0); Csb = (qsrc / T1 * d->vds + T2 * T4 * d->vds) * dAbulkCV_dVb + Csg * dVgsteff_dVb; Csd = (qsrc / T1 + T2 * T4) * AbulkCV + Csg * dVgsteff_dVd; Csg *= dVgsteff_dVg; }else{ /* 50/50 Charge petition model */ qsrc = -0.5 * (d->qgate + d->qbulk); Csg = -0.5 * (Cgg1 + Cbg1); Csb = -0.5 * (Cgb1 + Cbb1); Csd = -0.5 * (Cgd1 + Cbd1); } Cgb *= dVbseff_dVb; Cbb *= dVbseff_dVb; Csb *= dVbseff_dVb; } } d->qdrn = -(d->qgate + d->qbulk + qsrc); d->cggb = Cgg; d->cgsb = -(Cgg + Cgd + Cgb); d->cgdb = Cgd; d->cdgb = -(Cgg + Cbg + Csg); d->cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb); d->cddb = -(Cgd + Cbd + Csd); d->cbgb = Cbg; d->cbsb = -(Cbg + Cbd + Cbb); d->cbdb = Cbd; trace0("end capMod == 1"); }else if (m->capMod == 2) { trace0("begin capMod == 2"); double Qac0, dQac0_dVg, dQac0_dVd, dQac0_dVb; double Qsub0, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb; { double Vfbeff, dVfbeff_dVd, dVfbeff_dVg, dVfbeff_dVb; { const double DELTA_3 = 0.02; double V3 = Vfb - Vgs_eff + VbseffCV - DELTA_3; double T0, T2; if (Vfb <= 0.0) { T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * Vfb); T2 = -DELTA_3 / T0; }else{ T0 = sqrt(V3 * V3 + 4.0 * DELTA_3 * Vfb); T2 = DELTA_3 / T0; } double T1 = 0.5 * (1.0 + V3 / T0); Vfbeff = Vfb - 0.5 * (V3 + T0); dVfbeff_dVd = (1.0 - T1 - T2) * dVfb_dVd; dVfbeff_dVg = T1 * dVgs_eff_dVg; dVfbeff_dVb = (1.0 - T1 - T2) * dVfb_dVb - T1 * dVbseffCV_dVb; } trace3("", Vfbeff, dVfbeff_dVg, dVfbeff_dVb); trace1("", dVfbeff_dVd); //double Qac0, dQac0_dVg, dQac0_dVd, dQac0_dVb; { Qac0 = CoxWL * (Vfbeff - Vfb); dQac0_dVg = CoxWL * dVfbeff_dVg; dQac0_dVd = CoxWL * (dVfbeff_dVd - dVfb_dVd); dQac0_dVb = CoxWL * (dVfbeff_dVb - dVfb_dVb); } //double Qsub0, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb; { double T0 = 0.5 * t->k1; double T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff; double T1, T2; if (t->k1 == 0.0) { T1 = 0.0; T2 = 0.0; }else if (T3 < 0.0) { T1 = T0 + T3 / t->k1; T2 = CoxWL; }else{ T1 = sqrt(T0 * T0 + T3); T2 = CoxWL * T0 / T1; } Qsub0 = CoxWL * t->k1 * (T1 - T0); dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg); dQsub0_dVd = -T2 * (dVfbeff_dVd + dVgsteff_dVd); dQsub0_dVb = -T2 * (dVfbeff_dVb +dVbseffCV_dVb +dVgsteff_dVb); } } trace3("", Qac0, dQac0_dVg, dQac0_dVb); trace1("", dQac0_dVd); trace4("", Qsub0, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb); double AbulkCV = Abulk0 * s->abulkCVfactor; double dAbulkCV_dVb = s->abulkCVfactor * dAbulk0_dVb; trace2("", AbulkCV, dAbulkCV_dVb); double VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb; { const double DELTA_4 = 0.02; double VdsatCV = Vgsteff / AbulkCV; double V4 = VdsatCV - d->vds - DELTA_4; double T0 = sqrt(V4 * V4 + 4.0 * DELTA_4 * VdsatCV); VdseffCV = VdsatCV - 0.5 * (V4 + T0); double T1 = 0.5 * (1.0 + V4 / T0); double T2 = DELTA_4 / T0; double T3 = (1.0 - T1 - T2) / AbulkCV; dVdseffCV_dVg = T3; dVdseffCV_dVd = T1; dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb; } trace4("", VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb); double T0 = AbulkCV * VdseffCV; double T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1e-20); trace2("", T0, T1); double Cgg1, Cgd1, Cgb1, Cbg1, Cbd1, Cbb1; // also 1st estimate of d->qgate, d->qbulk { double T2 = VdseffCV / T1; double T3 = T0 * T2; double T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV); double T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5); double T6 = 12.0 * T2 * T2 * Vgsteff; d->qgate = CoxWL * (Vgsteff - 0.5 * VdseffCV + T3); Cgg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); Cgd1 = CoxWL * T5 * dVdseffCV_dVd + Cgg1 * dVgsteff_dVd; Cgb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Cgg1 * dVgsteff_dVb; Cgg1 *= dVgsteff_dVg; double T7 = 1.0 - AbulkCV; d->qbulk = CoxWL * T7 * (0.5 * VdseffCV - T3); T4 = -T7 * (T4 - 1.0); T5 = -T7 * T5; T6 = -(T7 * T6 + (0.5 * VdseffCV - T3)); Cbg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); Cbd1 = CoxWL * T5 * dVdseffCV_dVd + Cbg1 * dVgsteff_dVd; Cbb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Cbg1 * dVgsteff_dVb; Cbg1 *= dVgsteff_dVg; } trace3("", Cgg1, Cgd1, Cgb1); trace3("", Cbg1, Cbd1, Cbb1); trace2("2-1", d->qgate, d->qbulk); double Csg, Csd, Csb; trace1("", m->xpart); if (m->xpart > 0.5) { trace0("0/100 Charge petition model"); T1 = T1 + T1; qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 - T0 * T0 / T1); double T7 = (4.0 * Vgsteff - T0) / (T1 * T1); double T4 = -(0.5 + 24.0 * T0 * T0 / (T1 * T1)); double T5 = -(0.25 * AbulkCV - 12.0 * AbulkCV * T0 * T7); double T6 = -(0.25 * VdseffCV - 12.0 * T0 * VdseffCV * T7); Csg = CoxWL * (T4 + T5 * dVdseffCV_dVg); Csd = CoxWL * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd; Csb = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Csg * dVgsteff_dVb; Csg *= dVgsteff_dVg; }else if (m->xpart < 0.5) { trace0("40/60 Charge petition model"); T1 = T1 / 12.0; double T2 = 0.5 * CoxWL / (T1 * T1); double T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff * (Vgsteff - 4.0 * T0 / 3.0)) - 2.0 * T0 * T0 * T0 / 15.0; qsrc = -T2 * T3; double T7 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0) + 0.4 * T0 * T0; double T4 = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0 * Vgsteff - 8.0 * T0 / 3.0) + 2.0 * T0 * T0 / 3.0); double T5 = (qsrc / T1 + T2 * T7) * AbulkCV; double T6 = (qsrc / T1 * VdseffCV + T2 * T7 * VdseffCV); Csg = (T4 + T5 * dVdseffCV_dVg); Csd = T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd; Csb = (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Csg * dVgsteff_dVb; Csg *= dVgsteff_dVg; }else{ trace0("50/50 Charge petition model"); qsrc = -0.5 * (d->qgate + d->qbulk); Csg = -0.5 * (Cgg1 + Cbg1); Csb = -0.5 * (Cgb1 + Cbb1); Csd = -0.5 * (Cgd1 + Cbd1); } trace4("", Csg, Csd, Csb, qsrc); d->qgate += Qac0 + Qsub0; d->qbulk -= (Qac0 + Qsub0); d->qdrn = -(d->qgate + d->qbulk + qsrc); trace3("2-2", d->qgate, d->qbulk, d->qdrn); double Cgg = dQac0_dVg + dQsub0_dVg + Cgg1; double Cgd = dQac0_dVd + dQsub0_dVd + Cgd1; double Cgb = dQac0_dVb + dQsub0_dVb + Cgb1; trace3("", Cgg, Cgd, Cgb); double Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg; double Cbd = Cbd1 - dQac0_dVd - dQsub0_dVd; double Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb; trace3("", Cbg, Cbd, Cbb); Cgb *= dVbseff_dVb; Cbb *= dVbseff_dVb; Csb *= dVbseff_dVb; trace3("adjusted", Cgb, Cbb, Csb); d->cggb = Cgg; d->cgsb = -(Cgg + Cgd + Cgb); d->cgdb = Cgd; d->cdgb = -(Cgg + Cbg + Csg); d->cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb); d->cddb = -(Cgd + Cbd + Csd); d->cbgb = Cbg; d->cbsb = -(Cbg + Cbd + Cbb); d->cbdb = Cbd; trace0("end capMod == 2"); }else{ error(bDANGER, "illegal capmod = %d\n", int(m->capMod)); d->qbulk = d->qgate = NOT_VALID; } /* Non-quasi-static Model */ double tconst; if (m->nqsMod) { // d->gtau double qcheq = -d->qbulk - d->qgate; double T0 = s->leffCV * s->leffCV; tconst = t->u0temp * s->elm / CoxWL / T0; if (qcheq == 0.0) { tconst = 0.0; }else if (qcheq < 0.0) { tconst = -tconst; }else{ } double gtau_drift = std::abs(tconst * qcheq); double gtau_diff = 16.0 * t->u0temp * t->vtm / T0; d->gtau = gtau_drift + gtau_diff; d->cqgb = -(d->cggb + d->cbgb); d->cqdb = -(d->cgdb + d->cbdb); d->cqsb = -(d->cgsb + d->cbsb); d->cqbb = d->cggb +d->cgdb +d->cgsb +d->cbgb +d->cbdb +d->cbsb; d->qbulk = d->qgate = d->qdrn = qsrc = 0.0; d->cggb = d->cgsb = d->cgdb = 0.0; d->cdgb = d->cdsb = d->cddb = 0.0; d->cbgb = d->cbsb = d->cbdb = 0.0; #if 0 *(ckt->CKTstate0 + d->qcheq) = qcheq; if (ckt->CKTmode & MODEINITTRAN) *(ckt->CKTstate1 + d->qcheq) = *(ckt->CKTstate0 + d->qcheq); error = NIintegrate(ckt, &geq, &ceq, 0.0, d->qcheq); if (error) return (error); #endif }else{ d->gtau = 0.0; d->cqgb = d->cqdb = d->cqsb = d->cqbb = 0.0; } } } trace0("mos7"); trace3("", d->qgate, d->qdrn, d->qbulk); trace3("", d->cggb, d->cgsb, d->cgdb); trace3("", d->cdgb, d->cdsb, d->cddb); trace3("", d->cbgb, d->cbsb, d->cbdb); trace2("", d->ids, d->gds); trace4("", d->gmf, d->gmr, d->gmbf, d->gmbr); trace4("", d->isub, d->gbbs, d->gbgs, d->gbds); trace4("", d->qgate, d->cggb, d->cgsb, d->cgdb); trace4("", d->qdrn, d->cdgb, d->cdsb, d->cddb); trace4("", d->qbulk, d->cbgb, d->cbsb, d->cbdb); trace1("", d->gtau); trace4("", d->cqgb, d->cqsb, d->cqdb, d->cqbb); trace1("", d->tconst); trace2("", d->cgb, d->qgb); trace2("", d->qgd, d->cgd); trace2("", d->qgs, d->cgs); trace3("", d->vgs, d->vds, d->vbs); trace3("", d->vdsat, d->vgst, d->von); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_mos8.model������������������������������������������������������������������������������������0000664�0000000�0000000�00000272373�11454012162�0014072�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: d_mos8.model,v 26.132 2009/11/24 04:26:37 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Berkeley BSIM3v3.3 model ********** derived from......... * Copyright 2004 Regents of the University of California. All rights reserved. * File: b3ld.c of BSIM3v3.3.0 * Author: 1991 JianHui Huang and Min-Chie Jeng. * Modified by Mansun Chan (1995). * Author: 1997-1999 Weidong Liu. * Author: 2001 Xuemei Xi * Modified by Xuemei Xi, 10/05, 12/21, 2001. * Modified by Xuemei Xi, 07/29/2005. ********** * Recoded for Gnucap model compiler, Al Davis, 2006 */ h_headers { #include "d_mos_base.h" } cc_headers { #include "l_compar.h" #include "l_denoise.h" } /*--------------------------------------------------------------------------*/ /* from diode no fc??? double bulkJctPotential "Source/drain junction built-in potential" name=PB default=1.0; double unitAreaJctCap "Source/drain bottom junction capacitance per unit area" name=CJ default=5.0E-4; double bulkJctBotGradingCoeff "Source/drain bottom junction capacitance grading coefficient" name=MJ default=0.5; double sidewallJctPotential "Source/drain sw junction capacitance built in potential" name=PBSW default=1.0; double unitLengthSidewallJctCap "Source/drain sw junction capacitance per unit periphery" name=CJSW default=5.0E-10; double bulkJctSideGradingCoeff "Source/drain sw junction capacitance grading coefficient" name=MJSW default=0.33; double kf "Flicker noise coefficient" name=KF default=0.0; double af "Flicker noise exponent" name=AF default=1.0; from mos_base no is??? double jctSatCurDensity "Source/drain junction reverse saturation current density" name=JS default=1.0E-4; double sheetResistance "Source-drain sheet resistance" name=RSH default=0.0; no rd??? no rs??? no cbd??? no cbs??? double cgso "Gate-source overlap capacitance per width" "CGSO default=NA; double cgdo "Gate-drain overlap capacitance per width" name=CGDO default=NA; double cgbo "Gate-bulk overlap capacitance per length" name=CGBO default=NA; */ model BUILT_IN_MOS8 { level 8 public_keys { nmos8 polarity=pN; pmos8 polarity=pP; nmos49 polarity=pN; pmos49 polarity=pP; } dev_type BUILT_IN_MOS; inherit BUILT_IN_MOS_BASE; independent { override { double mjsw "" final_default=.33; double pb "" final_default=1.0 quiet_min=0.1; double pbsw "" final_default=pb quiet_min=0.1; double cjo "" default=5.0E-4; double cgdo "" final_default="(((dlc != NA) && (dlc > 0.0)) ? dlc * cox - cgdl.nom() : 0.6 * xj.nom() * cox)"; double cgso "" final_default="(((dlc != NA) && (dlc > 0.0)) ? dlc * cox - cgsl.nom() : 0.6 * xj.nom() * cox)"; double cgbo "" final_default="((dwc != NA) ? 2.0 * dwc * cox : 2.0 * Wint * cox)"; /* assumes cg?? final_default is BEFORE d?c final_default */ int cmodel "CMODEL" print_test="cmodel!=0" calculate="((!cmodel)?0:cmodel)"; bool needs_isub "" calculate="(alpha0.nom()!=0.)"; int mos_level "back-annotate for diode" name=DIODElevel print_test="mos_level != LEVEL" default=LEVEL; } raw_parameters { int capMod "Capacitance model selector (0, 1, 2, other?)" name=CAPMOD default=3; int nqsMod "Non-quasi-static model selector (0, !0)" name=NQSMOD default=0; int mobMod "Mobility model selector (1,2,3,other?)" name=MOBMOD default=1; int noiMod "Noise model selector (not used)" name=NOIMOD default=1; int paramChk "Model parameter checking selector (not used)" name=PARAMCHK default=0; int binUnit "Bin unit selector (1, !1)" name=BINUNIT default=1; double version "parameter for model version (not used)" name=VERSION default=3.3; double tox "Gate oxide thickness in meters" name=TOX default=150.0e-10; double xpart "Channel charge partitioning" name=XPART default=0.0; double jctSidewallSatCurDensity "Sidewall junction reverse saturation current density" name=JSW default=0.0; double mjswg "Source/drain (gate side) sw junction capacitance grading coefficient" name=MJSWG default=NA final_default=mjsw; double pbswg "Source/drain (gate side) sw junction capacitance built in potential" name=PBSWG default=NA final_default=pbsw quiet_min=0.1; double unitLengthGateSidewallJctCap "Source/drain (gate side) sidewall junction capacitance per unit width" name=CJSWG default=NA final_default=cjsw; double jctEmissionCoeff "Source/drain junction emission coefficient" name=NJ default=1.0; double jctTempExponent "Junction current temperature exponent" name=XTI default=3.0; double Lint "Length reduction parameter" name=LINT default=0.0; double Ll "Length reduction parameter" name=LL default=0.0; double Lln "Length reduction parameter" name=LLN default=1.0; double Lw "Length reduction parameter" name=LW default=0.0; double Lwn "Length reduction parameter" name=LWN default=1.0; double Lwl "Length reduction parameter" name=LWL default=0.0; double Wint "Width reduction parameter" name=WINT default=0.0; double Wl "Width reduction parameter" name=WL default=0.0; double Wln "Width reduction parameter" name=WLN default=1.0; double Ww "Width reduction parameter" name=WW default=0.0; double Wwn "Width reduction parameter" name=WWN default=1.0; double Wwl "Width reduction parameter" name=WWL default=0.0; double dwc "Delta W for C-V model" name=DWC default=NA final_default=Wint; double dlc "Delta L for C-V model" name=DLC default=NA final_default=Lint; double noia "Flicker noise parameter, oxide trap density A" name=NOIA default=NA final_default="(polarity==pN) ? 1e20 : 9.9e18"; double noib "Flicker noise parameter, oxide trap density B" name=NOIB default=NA final_default="(polarity==pN) ? 5e4 : 2.4e3"; double noic "Flicker noise parameter, oxide trap density C" name=NOIC default=NA final_default="(polarity==pN) ?-1.4e-12 :1.4e-12"; double em "Flicker noise parameter V/m" name=EM default=4.1e7; double ef "Flicker noise frequency exponent" name=EF default=1.0; // version 3.3 int acnqsMod "AC NQS model selector" name=ACNQSMOD default=0 quiet_max=1; double toxm "Gate oxide thickness used in extraction" name=TOXM default=tox; double lintnoi "lint offset for noise calculation" name=LINTNOI default=0.0; double ijth "Diode limiting current" name=IJTH default=0.1; double tpb "Temperature coefficient of pb" name=TPB default=0.0; double tcj "Temperature coefficient of cj" name=TCJ default=0.0; double tpbsw "Temperature coefficient of pbsw" name=TPBSW default=0.0; double tcjsw "Temperature coefficient of cjsw" name=TCJSW default=0.0; double tpbswg "Temperature coefficient of pbswg" name=TPBSWG default=0.0; double tcjswg "Temperature coefficient of cjswg" name=TCJSWG default=0.0; double Llc "Length reduction parameter for CV" name=LLC default=Ll; double Lwc "Length reduction parameter for CV" name=LWC default=Lw; double Lwlc "Length reduction parameter for CV" name=LWLC default=Lwl; double Wlc "Width reduction parameter for CV" name=WLC default=Wl; double Wwc "Width reduction parameter for CV" name=WWC default=Ww; double Wwlc "Width reduction parameter for CV" name=WWLC default=Wwl; // level 49 parameters, probably dummy for now int acm "area calculation method, ignored" name=ACM default=10; } calculated_parameters { double cox; double factor1 "" calculate="sqrt(tox * P_EPS_SI / P_EPS_OX)"; double vt_at_tnom "" calculate="tnom_k * P_K_Q"; double ni "" calculate="(1.45e10 * (tnom_k / 300.15) * sqrt(tnom_k / 300.15) * exp(21.5565981 - egap / (2.0 * vt_at_tnom)))"; } code_pre { //tox = std::max(tox, 1e-20); cox = 3.453133e-11 / tox; } code_post { if (npeak.nom() > 1.0e20) { npeak.set_nom(npeak.nom() * 1.0e-6); } if (ngate.nom() > 1.0e23) { ngate.set_nom(ngate.nom() * 1.0e-6); } } } size_dependent { raw_parameters { double cdsc "Drain/Source and channel coupling capacitance Q/V/m^2" name=CDSC default=2.4e-4; double cdscb "Body-bias dependence of cdsc Q/V/m^2" name=CDSCB default=0.0; double cdscd "Drain-bias dependence of cdsc Q/V/m^2" name=CDSCD default=0.0; double cit "Interface state capacitance Q/V/m^2" name=CIT default=0.0; double nfactor "Subthreshold swing Coefficient" name=NFACTOR default=1; double xj "Junction depth in meters" name=XJ default=.15e-6; double vsat "Saturation velocity at tnom m/s" name=VSAT default=8.0e4; double at "Temperature coefficient of vsat m/s" name=AT default=3.3e4; double a0 "Non-uniform depletion width effect coefficient." name=A0 default=1.0; double ags "Gate bias coefficient of Abulk." name=AGS default=0.0; double a1 "Non-saturation effect coefficient" name=A1 default=0.0; double a2 "Non-saturation effect coefficient" name=A2 default=1.0; double keta "Body-bias coefficient of non-uniform depletion width effect. 1/v" name=KETA default=-0.047; double nsub "Substrate doping concentration 1/cm3" name=NSUB default=6.0e16; double npeak "Channel doping concentration 1/cm3" name=NCH default=NA; double ngate "Poly-gate doping concentration 1/cm3" name=NGATE default=0.0; double gamma1 "Vth body coefficient" name=GAMMA1 default=NA; double gamma2 "Vth body coefficient" name=GAMMA2 default=NA; double vbx "Vth transition body Voltage" name=VBX default=NA; double vbm "Maximum body voltage" name=VBM default=-3.0; double xt "Doping depth" name=XT default=1.55e-7; double k1 "Bulk effect coefficient 1" name=K1 default=NA; double kt1 "Temperature coefficient of Vth" name=KT1 default=-0.11; double kt1l "Temperature coefficient of Vth" name=KT1L default=0.0; double kt2 "Body-coefficient of kt1" name=KT2 default=0.022; double k2 "Bulk effect coefficient 2" name=K2 default=NA; double k3 "Narrow width effect coefficient" name=K3 default=80.0; double k3b "Body effect coefficient of k3" name=K3B default=0.0; double w0 "Narrow width effect parameter" name=W0 default=2.5e-6; double nlx "Lateral non-uniform doping effect" name=NLX default=1.74e-7; double dvt0 "Short channel effect coeff. 0" name=DVT0 default=2.2; double dvt1 "Short channel effect coeff. 1" name=DVT1 default=0.53; double dvt2 "Short channel effect coeff. 2 1/v" name=DVT2 default=-0.032; double dvt0w "Narrow Width coeff. 0" name=DVT0W default=0.0; double dvt1w "Narrow Width effect coeff. 1" name=DVT1W default=5.3e6; double dvt2w "Narrow Width effect coeff. 2" name=DVT2W default=-0.032; double drout "DIBL coefficient of output resistance" name=DROUT default=0.56; double dsub "DIBL coefficient in the subthreshold region" name=DSUB default=NA final_default="drout"; double vth0 "Threshold voltage" name=VTH0 default=NA final_default=NA; double ua1 "Temperature coefficient of ua m/v" name=UA1 default=4.31e-9; double ua "Linear gate dependence of mobility m/v" name=UA default=2.25e-9; double ub1 "Temperature coefficient of ub (m/V)**2" name=UB1 default=-7.61e-18; double ub "Quadratic gate dependence of mobility (m/V)**2" name=UB default=5.87e-19; double uc1 "Temperature coefficient of uc" name=UC1 default=NA final_default="((m->mobMod==3) ? -0.056 : -0.056e-9)"; double uc "Body-bias dependence of mobility" name=UC default=NA final_default="((m->mobMod==3) ? -0.0465 : -0.0465e-9)"; double u0 "Low-field mobility at Tnom" name=U0 default=NA final_default="((m->polarity == pN) ? 0.067 : 0.025)"; double ute "Temperature coefficient of mobility" name=UTE default=-1.5; double voff "Threshold voltage offset" name=VOFF default=-0.08; double delta "Effective Vds parameter" name=DELTA default=0.01; double rdsw "Source-drain resistance per width" name=RDSW default=0.0; double prwg "Gate-bias effect on parasitic resistance" name=PRWG default=0.0; double prwb "Body-effect on parasitic resistance" name=PRWB default=0.0; double prt "Temperature coefficient of parasitic resistance" name=PRT default=0.0; double eta0 "Subthreshold region DIBL coefficient" name=ETA0 default=0.08; double etab "Subthreshold region DIBL coefficient 1/v" name=ETAB default=-0.07; double pclm "Channel length modulation Coefficient" name=PCLM default=1.3; double pdibl1 "Drain-induced barrier lowering coefficient" name=PDIBLC1 default=.39; double pdibl2 "Drain-induced barrier lowering coefficient" name=PDIBLC2 default=0.0086; double pdiblb "Body-effect on drain-induced barrier lowering 1/v" name=PDIBLCB default=0.0; double pscbe1 "Substrate current body-effect coefficient" name=PSCBE1 default=4.24e8; double pscbe2 "Substrate current body-effect coefficient" name=PSCBE2 default=1.0e-5; double pvag "Gate dependence of output resistance parameter" name=PVAG default=0.0; double wr "Width dependence of rds" name=WR default=1.0; double dwg "Width reduction parameter" name=DWG default=0.0; double dwb "Width reduction parameter" name=DWB default=0.0; double b0 "Abulk narrow width parameter" name=B0 default=0.0; double b1 "Abulk narrow width parameter" name=B1 default=0.0; double alpha0 "substrate current model parameter" name=ALPHA0 default=0.0; double beta0 "substrate current model parameter" name=BETA0 default=30.0; /* CV model */ double elm "Non-quasi-static Elmore Constant Parameter" name=ELM default=5.0; double vfbcv "Flat Band Voltage parameter for capmod=0 only" name=VFBCV default=-1.0; double cgsl "New C-V model parameter" name=CGSL default=0.0; double cgdl "New C-V model parameter" name=CGDL default=0.0; double ckappa "New C-V model parameter" name=CKAPPA default=0.6; double cf "Fringe capacitance parameter" name=CF default=NA final_default="2.0 * P_EPS_OX / M_PI * log(1.0 + 0.4e-6 / m->tox)"; double clc "Vdsat parameter for C-V model" name=CLC default=0.1e-6; double cle "Vdsat parameter for C-V model" name=CLE default=0.6; // version 3.3 double vfb "Flat Band Voltage" name=VFB default=NA; double acde "Exponential coefficient for finite charge thickness, capmod=3" name=ACDE default=1.0 quiet_min=0.4 quiet_max=1.6; double moin "Coefficient for gate-bias dependent surface potential, capmod=3" name=MOIN default=15.0 quiet_min=5.0 quiet_max=25.0; double noff "C-V turn-on/off parameter, capmod=1,2,3" name=NOFF default=1.0 quiet_min=0.1 quiet_max=4.0; double voffcv "C-V lateral-shift parameter, capmod=1,2,3" name=VOFFCV default=0.0 quiet_min=-0.5 quiet_max=0.5; double alpha1 "substrate current model parameter" name=ALPHA1 default=0.0; } calculated_parameters { double dl; double dlc; double dw; double dwc; double leff; /* BUG:: why not reuse from super */ double weff; double leffCV; double weffCV; double abulkCVfactor "" calculate="1.0 + pow((clc / leff), cle)"; double litl "" calculate="sqrt(3.0 * xj * m->tox)"; // version 3.3 double ldeb; } code_pre { { double T0 = pow(c->l_in, m->Lln); double T1 = pow(c->w_in, m->Lwn); double tmp1 = m->Ll / T0 + m->Lw / T1 + m->Lwl / (T0 * T1); dl = m->Lint + tmp1; dlc = m->dlc + tmp1; } { double T2 = pow(c->l_in, m->Wln); double T3 = pow(c->w_in, m->Wwn); double tmp2 = m->Wl / T2 + m->Ww / T3 + m->Wwl / (T2 * T3); dw = m->Wint + tmp2; dwc = m->dwc + tmp2; } leff = c->l_in - 2.0 * dl; weff = c->w_in - 2.0 * dw; leffCV = c->l_in - 2.0 * dlc; weffCV = c->w_in - 2.0 * dwc; cgate = m->cox * w_eff * l_eff; /* BUG:: not adjusted values?? */ double L = leff; double W = weff; if (m->binUnit == 1) { L /= MICRON2METER; W /= MICRON2METER; } } code_post { cgso = (m->cgso + cf) * weffCV; cgdo = (m->cgdo + cf) * weffCV; cgbo = m->cgbo * leffCV; if (u0 > 1.0) { u0 /= 1.0e4; } if (m->npeak.nom() == NA) { if (m->gamma1.nom() != NA) { double T0 = gamma1 * m->cox; npeak = 3.021E22 * T0 * T0; }else{ npeak = 1.7e17; } } if (m->k1.nom() != NA && m->k2.nom() != NA) { if (m->k1.nom() == NA) { k1 = 0.53; } if (m->k2.nom() == NA) { k2 = -0.0186; } }else{ vbm = -std::abs(vbm); if (m->gamma1.nom() == NA) { gamma1 = 5.753e-12 * sqrt(npeak) / m->cox; } if (m->gamma2.nom() == NA) { gamma2 = 5.753e-12 * sqrt(nsub) / m->cox; } } // version 3.3 acde *= pow((npeak / 2.0e16), -0.25); ldeb = sqrt(P_EPS_SI * m->vt_at_tnom / (P_Q * npeak * 1.0e6)) / 3.0; } } temperature_dependent { calculated_parameters { double temp; double tempratio "" calculate="temp / m->tnom_k"; double tempratio_1 "" calculate="tempratio - 1"; double vtm "vtm" calculate="temp * P_K_Q"; double ua; double ub; double uc; double u0temp; double vsattemp; double rds0; double phi; double sqrtPhi; double phis3; double Xdep0; double vbi; double cdep0; double k1; double k2; double vbsc; double vth0; double vfb; double theta0vb0; double thetaRout; // version 3.3 double k1ox; double k2ox; double vfbzb; } code_pre { temp = d->_sim->_temp_c + P_CELSIUS0; double egap = 1.16 - 7.02e-4 * temp * temp / (temp + 1108.0); } code_post { const double EXP_THRESHOLD = 34.0; const double MIN_EXP = 1.713908431e-15; double jctTempSatCurDensity; double jctSidewallTempSatCurDensity; if (temp != m->tnom_k) { double T0 = m->egap / m->vt_at_tnom - egap / vtm + m->jctTempExponent * log(temp / m->tnom_k); double T1 = exp(T0 / m->jctEmissionCoeff); jctTempSatCurDensity = m->js * T1; jctSidewallTempSatCurDensity = m->jctSidewallSatCurDensity * T1; }else{ jctTempSatCurDensity = m->js; jctSidewallTempSatCurDensity = m->jctSidewallSatCurDensity; } if (jctTempSatCurDensity < 0.0) { jctTempSatCurDensity = 0.0; } if (jctSidewallTempSatCurDensity < 0.0) { jctSidewallTempSatCurDensity = 0.0; } { double T0 = (tempratio - 1.0); ua = s->ua + s->ua1 * T0; ub = s->ub + s->ub1 * T0; uc = s->uc + s->uc1 * T0; u0temp = s->u0 * pow(tempratio, s->ute); vsattemp = s->vsat - s->at * T0; rds0 = (s->rdsw + s->prt * T0) / pow(s->weff * 1E6, s->wr); rds0 = std::max(rds0,0.0); } phi = 2.0 * m->vt_at_tnom * log(s->npeak / m->ni); sqrtPhi = sqrt(phi); phis3 = sqrtPhi * phi; Xdep0 = sqrt(2.0 * P_EPS_SI / (P_Q * s->npeak * 1.0e6)) * sqrtPhi; vbi = m->vt_at_tnom * log(1.0e20 * s->npeak / (m->ni * m->ni)); cdep0 = sqrt(P_Q * P_EPS_SI * s->npeak * 1.0e6 / 2.0 / phi); if (m->k1.nom() != NA && m->k2.nom() != NA) { k2 = s->k2; k1 = s->k1; }else{ double vbx = (m->vbx.nom() == NA) ? -std::abs(phi - 7.7348e-4 * s->npeak * s->xt * s->xt) : -std::abs(s->vbx); double T0 = s->gamma1 - s->gamma2; double T1 = sqrt(phi - vbx) - sqrtPhi; double T2 = sqrt(phi * (phi - s->vbm)) - phi; k2 = T0 * T1 / (2.0 * T2 + s->vbm); k1 = s->gamma2 - 2.0 * k2 * sqrt(phi - s->vbm); } k1ox = k1 * m->tox / m->toxm; k2ox = k2 * m->tox / m->toxm; if (k2 < 0.) { double T0 = 0.5 * k1 / k2; vbsc = to_range(-30.0, (0.9 * (phi - T0 * T0)), -3.0); }else{ vbsc = -30.0; } vbsc = std::min(vbsc, s->vbm); if (s->vfb == NA) { if (s->vth0 == NA) { vfb = -1.0; }else{ vfb = m->polarity * s->vth0 - phi - k1 * sqrtPhi; } }else{ vfb = s->vfb; trace1("", s->vfb); } if (s->vth0 == NA) { vth0 = m->polarity * (vfb + phi + k1 * sqrtPhi); }else{ vth0 = s->vth0; } trace3("", s->vth0, vth0, vfb); { double T1 = sqrt(P_EPS_SI / P_EPS_OX * m->tox * Xdep0); double T0 = exp(-0.5 * s->dsub * s->leff / T1); theta0vb0 = (T0 + 2.0 * T0 * T0); T0 = exp(-0.5 * s->drout * s->leff / T1); double T2 = (T0 + 2.0 * T0 * T0); thetaRout = s->pdibl1 * T2 + s->pdibl2; } { // vfbzb double tmp1 = vbi - phi; double tmp2 = m->factor1 * sqrt(Xdep0); double T2; { double T0 = -0.5 * s->dvt1w * s->weff * s->leff / tmp2; double T1 = (T0 > -EXP_THRESHOLD) ? exp(T0) : MIN_EXP; T2 = T1 * (1.0 + 2.0 * T1); T0 = s->dvt0w * T2; T2 = T0 * tmp1; } double T3; { double T0 = -0.5 * s->dvt1 * s->leff / tmp2; double T1 = (T0 > -EXP_THRESHOLD) ? exp(T0) : MIN_EXP; double t2 = T1 * (1.0 + 2.0 * T1); T3 = s->dvt0 * t2 * tmp1; } double T4 = m->tox * phi / (s->weff + s->w0); double T5; { double T0 = sqrt(1.0 + s->nlx / s->leff); T5 = k1ox * (T0 - 1.0) * sqrtPhi + (s->kt1 + s->kt1l / s->leff) * (tempratio - 1.0); } { double tmp3 = m->polarity * vth0 - T2 - T3 + s->k3 * T4 + T5; vfbzb = tmp3 - phi - k1 * sqrtPhi; } } } } /*-----------------------------------------------------------------------*/ tr_eval { trace3("", d->vds, d->vgs, d->vbs); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const double EXP_THRESHOLD = 34.0; const double MIN_EXP = 1.713908431e-15; const double MAX_EXP = 5.834617425e14; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - d->reverse_if_needed(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double Vbseff, dVbseff_dVb; { double T0 = d->vbs - t->vbsc - 0.001; double T1 = sqrt(T0 * T0 - 0.004 * t->vbsc); trace3("", t->vbsc, T0, T1); Vbseff = t->vbsc + 0.5 * (T0 + T1); dVbseff_dVb = 0.5 * (1.0 + T0 / T1); trace2("raw", Vbseff, dVbseff_dVb); fixzero(&Vbseff, t->vbsc); if (Vbseff < d->vbs) { // From Spice, to fix numeric problems //untested(); // inadequately. Above fixzero should do a Vbseff = d->vbs; // better job, but I left this in case. } } trace2("fixed", Vbseff, dVbseff_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double Phis, dPhis_dVb, sqrtPhis, dsqrtPhis_dVb; if (Vbseff > 0.0) { //untested(); d->sbfwd = true; double T0 = t->phi / (t->phi + Vbseff); Phis = t->phi * T0; dPhis_dVb = -T0 * T0; sqrtPhis = t->phis3 / (t->phi + 0.5 * Vbseff); dsqrtPhis_dVb = -0.5 * sqrtPhis * sqrtPhis / t->phis3; trace0("bs-fwd-bias"); }else{ d->sbfwd = false; Phis = t->phi - Vbseff; dPhis_dVb = -1.0; sqrtPhis = sqrt(Phis); dsqrtPhis_dVb = -0.5 / sqrtPhis; trace0("bs-normal"); } trace4("", Phis, dPhis_dVb, sqrtPhis, dsqrtPhis_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double Xdep = t->Xdep0 * sqrtPhis / t->sqrtPhi; double dXdep_dVb = (t->Xdep0 / t->sqrtPhi) * dsqrtPhis_dVb; trace2("", Xdep, dXdep_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double Theta0, dTheta0_dVb; { double lt1, dlt1_dVb; { double T3 = sqrt(Xdep); double T0 = s->dvt2 * Vbseff; double T1, T2; if (T0 >= - 0.5) { T1 = 1.0 + T0; T2 = s->dvt2; trace4("", T0, T1, T2, T3); }else{ untested(); /* Added to avoid any discontinuity problems caused by dvt2 */ double T4 = 1.0 / (3.0 + 8.0 * T0); T1 = (1.0 + 3.0 * T0) * T4; T2 = s->dvt2 * T4 * T4; trace4("dvd2 fix", T0, T1, T2, T3); } lt1 = m->factor1 * T3 * T1; dlt1_dVb = m->factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2); } trace2("", lt1, dlt1_dVb); double T0 = -0.5 * s->dvt1 * s->leff / lt1; if (T0 > -EXP_THRESHOLD) { double T1 = exp(T0); Theta0 = T1 * (1.0 + 2.0 * T1); double dT1_dVb = -T0 / lt1 * T1 * dlt1_dVb; dTheta0_dVb = (1.0 + 4.0 * T1) * dT1_dVb; trace2("T0 > -ET", Theta0, dTheta0_dVb); }else{ double T1 = MIN_EXP; Theta0 = T1 * (1.0 + 2.0 * T1); dTheta0_dVb = 0.0; trace2("T0 < -ET", Theta0, dTheta0_dVb); } } trace2("", Theta0, dTheta0_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double dVth_dVb, dVth_dVd; // d->von { double V0 = t->vbi - t->phi; double T2, dT2_dVb; { double ltw, dltw_dVb; { double T3 = sqrt(Xdep); double T0 = s->dvt2w * Vbseff; double T1, t2; if (T0 >= - 0.5) { T1 = 1.0 + T0; t2 = s->dvt2w; }else{ untested(); /* Added to avoid any discontinuity problems caused by dvt2w */ double T4 = 1.0 / (3.0 + 8.0 * T0); T1 = (1.0 + 3.0 * T0) * T4; t2 = s->dvt2w * T4 * T4; } trace4("", T0, T1, t2, T3); ltw = m->factor1 * T3 * T1; dltw_dVb = m->factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * t2); } trace2("", ltw, dltw_dVb); double T0 = -0.5 * s->dvt1w * s->weff * s->leff / ltw; if (T0 > -EXP_THRESHOLD) { double T1 = exp(T0); T2 = T1 * (1.0 + 2.0 * T1); double dT1_dVb = -T0 / ltw * T1 * dltw_dVb; dT2_dVb = (1.0 + 4.0 * T1) * dT1_dVb; }else{ double T1 = MIN_EXP; T2 = T1 * (1.0 + 2.0 * T1); dT2_dVb = 0.0; } T0 = s->dvt0w * T2; T2 = T0 * V0; dT2_dVb = s->dvt0w * dT2_dVb * V0; } trace3("", V0, T2, dT2_dVb); double T0 = sqrt(1.0 + s->nlx / s->leff); double T1 = t->k1ox * (T0 - 1.0) * t->sqrtPhi + (s->kt1 + s->kt1l / s->leff + s->kt2 * Vbseff) * t->tempratio_1; double tmp2 = m->tox * t->phi / (s->weff + s->w0); double T3 = s->eta0 + s->etab * Vbseff; trace4("", T0, T1, tmp2, T3); double T4; if (T3 < 1.0e-4) { untested(); /* avoid discontinuity problems caused by etab */ double T9 = 1.0 / (3.0 - 2.0e4 * T3); T3 = (2.0e-4 - T3) * T9; T4 = T9 * T9; trace3("", T9, T3, T4); }else{ T4 = 1.0; trace1("", T4); } double thetavth = s->dvt0 * Theta0; double Delt_vth = thetavth * V0; double dDelt_vth_dVb = s->dvt0 * dTheta0_dVb * V0; trace4("", thetavth, t->theta0vb0, Delt_vth, dDelt_vth_dVb); double dDIBL_Sft_dVd = T3 * t->theta0vb0; double DIBL_Sft = dDIBL_Sft_dVd * d->vds; trace2("", dDIBL_Sft_dVd, DIBL_Sft); trace4("", t->vth0, t->k1, sqrtPhis, t->sqrtPhi); trace4("", t->k2, Vbseff, Delt_vth, T2); trace4("", s->k3, s->k3b, Vbseff, tmp2); trace2("", T1, DIBL_Sft); double Vth = m->polarity * t->vth0 + t->k1ox * sqrtPhis - t->k1 * t->sqrtPhi - t->k2ox * Vbseff - Delt_vth - T2 + (s->k3 + s->k3b * Vbseff) * tmp2 + T1 - DIBL_Sft; d->von = Vth; dVth_dVb = t->k1ox * dsqrtPhis_dVb - t->k2ox - dDelt_vth_dVb - dT2_dVb + s->k3b * tmp2 - s->etab * d->vds * t->theta0vb0 * T4 + s->kt2 * t->tempratio_1; dVth_dVd = -dDIBL_Sft_dVd; } trace3("", d->von, dVth_dVb, dVth_dVd); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Calculate n */ double n, dn_dVb, dn_dVd; { double tmp2 = s->nfactor * P_EPS_SI / Xdep; double tmp3 = s->cdsc + s->cdscb * Vbseff + s->cdscd * d->vds; double tmp4 = (tmp2 + tmp3 * Theta0 + s->cit) / m->cox; trace3("", tmp2, tmp3, tmp4); if (tmp4 >= -0.5) { n = 1.0 + tmp4; dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb + s->cdscb * Theta0) / m->cox; dn_dVd = s->cdscd * Theta0 / m->cox; trace3("n", n, dn_dVb, dn_dVd); }else{ /* avoid discontinuity problems caused by tmp4 */ double T0 = 1.0 / (3.0 + 8.0 * tmp4); n = (1.0 + 3.0 * tmp4) * T0; T0 *= T0; dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb + s->cdscb * Theta0) / m->cox * T0; dn_dVd = s->cdscd * Theta0 / m->cox * T0; trace3("n disc", n, dn_dVb, dn_dVd); } } trace3("", n, dn_dVb, dn_dVd); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Poly Gate Si Depletion Effect */ double Vgs_eff, dVgs_eff_dVg; { double T0 = t->vfb + t->phi; trace2("Poly", t->vfb, t->phi); trace3("", s->ngate, d->vgs, T0); if ((s->ngate > 1.e18) && (s->ngate < 1.e25) && (d->vgs > T0)) { /* added to avoid the problem caused by ngate */ double T1 = 1.0e6 * P_Q * P_EPS_SI * s->ngate / (m->cox * m->cox); double T4 = sqrt(1.0 + 2.0 * (d->vgs - T0) / T1); double T2 = T1 * (T4 - 1.0); double T3 = 0.5 * T2 * T2 / T1; /* T3 = Vpoly */ double T7 = 1.12 - T3 - 0.05; double T6 = sqrt(T7 * T7 + 0.224); double T5 = 1.12 - 0.5 * (T7 + T6); Vgs_eff = d->vgs - T5; dVgs_eff_dVg = 1.0 - (0.5 - 0.5 / T4) * (1.0 + T7 / T6); trace2("><", Vgs_eff, dVgs_eff_dVg); }else{ Vgs_eff = d->vgs; dVgs_eff_dVg = 1.0; trace2("const", Vgs_eff, dVgs_eff_dVg); } } trace2("", Vgs_eff, dVgs_eff_dVg); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Effective Vgst (Vgsteff) Calculation */ double /*Vgsteff,*/ dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb, Vgst2Vtm; // d->vgst { double Vgst = Vgs_eff - d->von; double T10 = 2.0 * n * t->vtm; double VgstNVt = Vgst / T10; double ExpArg = (2.0 * s->voff - Vgst) / T10; trace4("", Vgst, T10, VgstNVt, ExpArg); /* MCJ: Very small Vgst */ if (VgstNVt > EXP_THRESHOLD) { d->vgst = Vgst; dVgsteff_dVg = dVgs_eff_dVg; dVgsteff_dVd = -dVth_dVd; dVgsteff_dVb = -dVth_dVb; trace4(">>", d->vgst, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb); }else if (ExpArg > EXP_THRESHOLD) { double T0 = (Vgst - s->voff) / (n * t->vtm); double ExpVgst = exp(T0); d->vgst = t->vtm * t->cdep0 / m->cox * ExpVgst; dVgsteff_dVg = d->vgst / (n * t->vtm); dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + T0 * t->vtm * dn_dVd); dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + T0 * t->vtm * dn_dVb); dVgsteff_dVg *= dVgs_eff_dVg; trace4(">", d->vgst, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb); }else{ double ExpVgst = exp(VgstNVt); double T1 = T10 * log(1.0 + ExpVgst); double dT1_dVg = ExpVgst / (1.0 + ExpVgst); double dT1_dVb = -dT1_dVg * (dVth_dVb + Vgst / n * dn_dVb) + T1 / n * dn_dVb; double dT1_dVd = -dT1_dVg * (dVth_dVd + Vgst / n * dn_dVd) + T1 / n * dn_dVd; double dT2_dVg = -m->cox / (t->vtm * t->cdep0) * exp(ExpArg); double T2 = 1.0 - T10 * dT2_dVg; double dT2_dVd = -dT2_dVg * (dVth_dVd - 2.0 * t->vtm * ExpArg * dn_dVd) + (T2 - 1.0) / n * dn_dVd; double dT2_dVb = -dT2_dVg * (dVth_dVb - 2.0 * t->vtm * ExpArg * dn_dVb) + (T2 - 1.0) / n * dn_dVb; d->vgst = T1 / T2; double T3 = T2 * T2; dVgsteff_dVg = (T2 * dT1_dVg - T1 * dT2_dVg) / T3 * dVgs_eff_dVg; dVgsteff_dVd = (T2 * dT1_dVd - T1 * dT2_dVd) / T3; dVgsteff_dVb = (T2 * dT1_dVb - T1 * dT2_dVb) / T3; trace4("<", d->vgst, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb); } Vgst2Vtm = d->vgst + 2.0 * t->vtm; trace3("", d->vgst, t->vtm, Vgst2Vtm); } trace1("", d->vgst); trace4("", dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb, Vgst2Vtm); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Calculate Effective Channel Geometry */ double Weff, dWeff_dVg, dWeff_dVb; { double T9 = sqrtPhis - t->sqrtPhi; Weff = s->weff - 2.0 * (s->dwg * d->vgst + s->dwb * T9); dWeff_dVg = -2.0 * s->dwg; dWeff_dVb = -2.0 * s->dwb * dsqrtPhis_dVb; if (Weff < 2.0e-8) { /* to avoid the discontinuity problem due to Weff*/ double T0 = 1.0 / (6.0e-8 - 2.0 * Weff); Weff = 2.0e-8 * (4.0e-8 - Weff) * T0; T0 *= T0 * 4.0e-16; dWeff_dVg *= T0; dWeff_dVb *= T0; trace3("Weff fix", Weff, dWeff_dVg, dWeff_dVb); } } trace3("", Weff, dWeff_dVg, dWeff_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double Rds, dRds_dVg, dRds_dVb; { double T9 = sqrtPhis - t->sqrtPhi; double T0 = s->prwg * d->vgst + s->prwb * T9; if (T0 >= -0.9) { Rds = t->rds0 * (1.0 + T0); dRds_dVg = t->rds0 * s->prwg; dRds_dVb = t->rds0 * s->prwb * dsqrtPhis_dVb; }else{ /* to avoid the discontinuity problem due to prwg and prwb*/ double T1 = 1.0 / (17.0 + 20.0 * T0); Rds = t->rds0 * (0.8 + T0) * T1; T1 *= T1; dRds_dVg = t->rds0 * s->prwg * T1; dRds_dVb = t->rds0 * s->prwb * dsqrtPhis_dVb * T1; trace3("Rds fix", T9, T0, T1); trace3("Rds fix", Rds, dRds_dVg, dRds_dVb); } ////////// d->rds = Rds /* Noise Bugfix */ } trace3("", Rds, dRds_dVg, dRds_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Calculate Abulk */ double Abulk0, dAbulk0_dVb, dAbulk_dVg, Abulk, dAbulk_dVb; { double T1 = 0.5 * t->k1ox / sqrtPhis; double dT1_dVb = -T1 / sqrtPhis * dsqrtPhis_dVb; double T9 = sqrt(s->xj * Xdep); double tmp1 = s->leff + 2.0 * T9; double T5 = s->leff / tmp1; double tmp2 = s->a0 * T5; double tmp3 = s->weff + s->b1; double tmp4 = s->b0 / tmp3; double T2 = tmp2 + tmp4; double dT2_dVb = -T9 / tmp1 / Xdep * dXdep_dVb; double T6 = T5 * T5; double T7 = T5 * T6; Abulk0 = 1.0 + T1 * T2; dAbulk0_dVb = T1 * tmp2 * dT2_dVb + T2 * dT1_dVb; double T8 = s->ags * s->a0 * T7; dAbulk_dVg = -T1 * T8; Abulk = Abulk0 + dAbulk_dVg * d->vgst; dAbulk_dVb = dAbulk0_dVb - T8 * d->vgst * (dT1_dVb + 3.0 * T1 * dT2_dVb); trace2("1", Abulk0, dAbulk0_dVb); trace3("1", dAbulk_dVg, Abulk, dAbulk_dVb); if (Abulk0 < 0.1) { /* added to avoid the problems caused by Abulk0 */ double t9 = 1.0 / (3.0 - 20.0 * Abulk0); Abulk0 = (0.2 - Abulk0) * t9; dAbulk0_dVb *= t9 * t9; trace2("2", Abulk0, dAbulk0_dVb); } if (Abulk < 0.1) { /* added to avoid the problems caused by Abulk */ double t9 = 1.0 / (3.0 - 20.0 * Abulk); Abulk = (0.2 - Abulk) * t9; double T10 = t9 * t9; dAbulk_dVb *= T10; dAbulk_dVg *= T10; trace3("2", dAbulk_dVg, Abulk, dAbulk_dVb); } ////////// d->Abulk = Abulk double T0, dT0_dVb; { double t2 = s->keta * Vbseff; if (t2 >= -0.9) { T0 = 1.0 / (1.0 + t2); dT0_dVb = -s->keta * T0 * T0; trace3("", t2, T0, dT0_dVb); }else{ /* added to avoid the problems caused by Keta */ double t1 = 1.0 / (0.8 + t2); T0 = (17.0 + 20.0 * t2) * t1; dT0_dVb = -s->keta * t1 * t1; trace3("keta fix", t2, T0, dT0_dVb); } } dAbulk_dVg *= T0; dAbulk_dVb = dAbulk_dVb * T0 + Abulk * dT0_dVb; dAbulk0_dVb = dAbulk0_dVb * T0 + Abulk0 * dT0_dVb; Abulk *= T0; Abulk0 *= T0; ////////// d->AbovVgst2Vtm = Abulk / Vgst2Vtm } trace2("", Abulk0, dAbulk0_dVb); trace3("", dAbulk_dVg, Abulk, dAbulk_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Mobility calculation */ double ueff, dueff_dVg, dueff_dVd, dueff_dVb; { double Denomi, dDenomi_dVg, dDenomi_dVd, dDenomi_dVb; { double T5; if (m->mobMod == 1) { double T0 = d->vgst + d->von + d->von; double T2 = t->ua + t->uc * Vbseff; double T3 = T0 / m->tox; T5 = T3 * (T2 + t->ub * T3); dDenomi_dVg = (T2 + 2.0 * t->ub * T3) / m->tox; dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + t->uc * T3; }else if (m->mobMod == 2) { T5 = d->vgst / m->tox * (t->ua + t->uc * Vbseff + t->ub * d->vgst / m->tox); dDenomi_dVg = (t->ua + t->uc * Vbseff + 2.0 * t->ub * d->vgst / m->tox) / m->tox; dDenomi_dVd = 0.0; dDenomi_dVb = d->vgst * t->uc / m->tox; }else{ double T0 = d->vgst + d->von + d->von; double T2 = 1.0 + t->uc * Vbseff; double T3 = T0 / m->tox; double T4 = T3 * (t->ua + t->ub * T3); T5 = T4 * T2; dDenomi_dVg = (t->ua + 2.0 * t->ub * T3) * T2 / m->tox; dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + t->uc * T4; } if (T5 >= -0.8) { Denomi = 1.0 + T5; }else{ /* Added to avoid the discontinuity problem caused by ua and ub*/ double T9 = 1.0 / (7.0 + 10.0 * T5); Denomi = (0.6 + T5) * T9; T9 *= T9; dDenomi_dVg *= T9; dDenomi_dVd *= T9; dDenomi_dVb *= T9; } } ueff = t->u0temp / Denomi; double T9 = -ueff / Denomi; dueff_dVg = T9 * dDenomi_dVg; dueff_dVd = T9 * dDenomi_dVd; dueff_dVb = T9 * dDenomi_dVb; } trace4("", ueff, dueff_dVg, dueff_dVd, dueff_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double Esat, EsatL, dEsatL_dVg, dEsatL_dVd, dEsatL_dVb; { Esat = 2.0 * t->vsattemp / ueff; EsatL = Esat * s->leff; double T0 = -EsatL /ueff; dEsatL_dVg = T0 * dueff_dVg; dEsatL_dVd = T0 * dueff_dVd; dEsatL_dVb = T0 * dueff_dVb; } trace2("", Esat, EsatL); trace3("", dEsatL_dVg, dEsatL_dVd, dEsatL_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Saturation Drain Voltage Vdsat */ double Vdsat, dVdsat_dVg, dVdsat_dVd, dVdsat_dVb; // d->vdsat double Vasat, dVasat_dVg, dVasat_dVb, dVasat_dVd; { double WVCoxRds; { double WVCox = Weff * t->vsattemp * m->cox; WVCoxRds = WVCox * Rds; } trace1("", WVCoxRds); double Lambda, dLambda_dVg; { if (s->a1 == 0.0) { Lambda = s->a2; dLambda_dVg = 0.0; }else if (s->a1 > 0.0) { /* avoid discontinuity problem caused by s->a1 and s->a2 (Lambda) */ double T0 = 1.0 - s->a2; double T1 = T0 - s->a1 * d->vgst - 0.0001; double T2 = sqrt(T1 * T1 + 0.0004 * T0); Lambda = s->a2 + T0 - 0.5 * (T1 + T2); dLambda_dVg = 0.5 * s->a1 * (1.0 + T1 / T2); }else{ double T1 = s->a2 + s->a1 * d->vgst - 0.0001; double T2 = sqrt(T1 * T1 + 0.0004 * s->a2); Lambda = 0.5 * (T1 + T2); dLambda_dVg = 0.5 * s->a1 * (1.0 + T1 / T2); } } trace2("", Lambda, dLambda_dVg); double tmp2, tmp3; if (Rds > 0) { tmp2 = dRds_dVg / Rds + dWeff_dVg / Weff; tmp3 = dRds_dVb / Rds + dWeff_dVb / Weff; }else{ tmp2 = dWeff_dVg / Weff; tmp3 = dWeff_dVb / Weff; } trace2("", tmp2, tmp3); //double Vdsat, dVdsat_dVg, dVdsat_dVd, dVdsat_dVb; // d->vdsat double tmp1; { if ((Rds == 0.0) && (Lambda == 1.0)) { double T0 = 1.0 / (Abulk * EsatL + Vgst2Vtm); tmp1 = 0.0; double T1 = T0 * T0; double T2 = Vgst2Vtm * T0; double T3 = EsatL * Vgst2Vtm; Vdsat = T3 * T0; double dT0_dVg = -(Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 1.0)*T1; double dT0_dVd = -(Abulk * dEsatL_dVd) * T1; double dT0_dVb = -(Abulk * dEsatL_dVb + dAbulk_dVb * EsatL) * T1; dVdsat_dVg = T3 * dT0_dVg + T2 * dEsatL_dVg + EsatL * T0; dVdsat_dVd = T3 * dT0_dVd + T2 * dEsatL_dVd; dVdsat_dVb = T3 * dT0_dVb + T2 * dEsatL_dVb; }else{ tmp1 = dLambda_dVg / (Lambda * Lambda); double T9 = Abulk * WVCoxRds; double T8 = Abulk * T9; double T7 = Vgst2Vtm * T9; double T6 = Vgst2Vtm * WVCoxRds; double T0 = 2.0 * Abulk * (T9 - 1.0 + 1.0 / Lambda); double dT0_dVg = 2.0 * (T8 * tmp2 - Abulk * tmp1 + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbulk_dVg); double dT0_dVb = 2.0 * (T8 * (2.0 / Abulk * dAbulk_dVb + tmp3) + (1.0 / Lambda - 1.0) * dAbulk_dVb); //double dT0_dVd = 0.0; double T1 = Vgst2Vtm * (2.0 / Lambda - 1.0) + Abulk * EsatL + 3.0*T7; double dT1_dVg = (2.0 / Lambda - 1.0) - 2.0 * Vgst2Vtm * tmp1 + Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 3.0 * (T9 + T7 * tmp2 + T6 * dAbulk_dVg); double dT1_dVb = Abulk * dEsatL_dVb + EsatL * dAbulk_dVb + 3.0 * (T6 * dAbulk_dVb + T7 * tmp3); double dT1_dVd = Abulk * dEsatL_dVd; double T2 = Vgst2Vtm * (EsatL + 2.0 * T6); double dT2_dVg = EsatL + Vgst2Vtm * dEsatL_dVg + T6 * (4.0 + 2.0 * Vgst2Vtm * tmp2); double dT2_dVb = Vgst2Vtm * (dEsatL_dVb + 2.0 * T6 * tmp3); double dT2_dVd = Vgst2Vtm * dEsatL_dVd; double T3 = sqrt(T1 * T1 - 2.0 * T0 * T2); Vdsat = (T1 - T3) / T0; dVdsat_dVg = (dT1_dVg - (T1 * dT1_dVg - dT0_dVg * T2 - T0 * dT2_dVg) / T3 - Vdsat * dT0_dVg) / T0; dVdsat_dVb = (dT1_dVb - (T1 * dT1_dVb - dT0_dVb * T2 - T0 * dT2_dVb) / T3 - Vdsat * dT0_dVb) / T0; dVdsat_dVd = (dT1_dVd - (T1 * dT1_dVd - T0 * dT2_dVd) / T3) / T0; } d->vdsat = Vdsat; d->saturated = (d->vds >= d->vdsat); } trace1("", tmp1); trace4("d->vdsat", Vdsat, dVdsat_dVg, dVdsat_dVd, dVdsat_dVb); /* Calculate VAsat */ // double Vasat, dVasat_dVg, dVasat_dVb, dVasat_dVd; { double tmp4 = 1.0 - 0.5 * Abulk * Vdsat / Vgst2Vtm; double T9 = WVCoxRds * d->vgst; double T8 = T9 / Vgst2Vtm; double T0 = EsatL + Vdsat + 2.0 * T9 * tmp4; double T7 = 2.0 * WVCoxRds * tmp4; double dT0_dVg = dEsatL_dVg + dVdsat_dVg + T7 * (1.0 + tmp2 * d->vgst) - T8 * (Abulk * dVdsat_dVg - Abulk * Vdsat / Vgst2Vtm + Vdsat * dAbulk_dVg); double dT0_dVb = dEsatL_dVb + dVdsat_dVb + T7 * tmp3 * d->vgst - T8 * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb); double dT0_dVd = dEsatL_dVd + dVdsat_dVd - T8 * Abulk * dVdsat_dVd; T9 = WVCoxRds * Abulk; double T1 = 2.0 / Lambda - 1.0 + T9; double dT1_dVg = -2.0 * tmp1 + WVCoxRds * (Abulk * tmp2 + dAbulk_dVg); double dT1_dVb = dAbulk_dVb * WVCoxRds + T9 * tmp3; Vasat = T0 / T1; dVasat_dVg = (dT0_dVg - Vasat * dT1_dVg) / T1; dVasat_dVb = (dT0_dVb - Vasat * dT1_dVb) / T1; dVasat_dVd = dT0_dVd / T1; } trace4("", Vasat, dVasat_dVg, dVasat_dVb, dVasat_dVd); } trace1("", d->vdsat); trace4("", Vdsat, dVdsat_dVg, dVdsat_dVd, dVdsat_dVb); trace4("", Vasat, dVasat_dVg, dVasat_dVb, dVasat_dVd); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Effective Vds (Vdseff) Calculation */ double Vdseff, diffVds, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb; { double T1 = Vdsat - d->vds - s->delta; double dT1_dVg = dVdsat_dVg; double dT1_dVd = dVdsat_dVd - 1.0; double dT1_dVb = dVdsat_dVb; trace4("", T1, dT1_dVg, dT1_dVd, dT1_dVb); double T2 = sqrt(T1 * T1 + 4.0 * s->delta * Vdsat); double T0 = T1 / T2; double T3 = 2.0 * s->delta / T2; trace3("", T2, T0, T3); double dT2_dVg = T0 * dT1_dVg + T3 * dVdsat_dVg; double dT2_dVd = T0 * dT1_dVd + T3 * dVdsat_dVd; double dT2_dVb = T0 * dT1_dVb + T3 * dVdsat_dVb; trace3("", dT2_dVg, dT2_dVd, dT2_dVb); Vdseff = Vdsat - 0.5 * (T1 + T2); dVdseff_dVg = dVdsat_dVg - 0.5 * (dT1_dVg + dT2_dVg); dVdseff_dVd = dVdsat_dVd - 0.5 * (dT1_dVd + dT2_dVd); dVdseff_dVb = dVdsat_dVb - 0.5 * (dT1_dVb + dT2_dVb); trace4("raw", Vdseff, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb); fixzero(&Vdseff, Vdsat); fixzero(&dVdseff_dVg, dVdsat_dVg); fixzero(&dVdseff_dVd, dVdsat_dVd); fixzero(&dVdseff_dVb, dVdsat_dVb); /* Added to eliminate non-zero Vdseff at Vds=0.0 */ if (d->vds == 0.0) { assert(Vdseff == 0.0); assert(dVdseff_dVg == 0.0); assert(dVdseff_dVb == 0.0); } if (Vdseff > d->vds) { // From Spice, to fix numeric problems. trace2("numeric problems", Vdseff, d->vds); Vdseff = d->vds; } trace4("fixed", Vdseff, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb); diffVds = d->vds - Vdseff; trace2("", Vdseff, diffVds); ////////// d->Vdseff = Vdseff; } trace2("", Vdseff, diffVds); trace3("", dVdseff_dVg, dVdseff_dVd, dVdseff_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Calculate Ids */ double Idsa, dIdsa_dVg, dIdsa_dVd, dIdsa_dVb; { double Va, dVa_dVg, dVa_dVd, dVa_dVb; { /* Calculate VACLM */ double VACLM, dVACLM_dVg, dVACLM_dVb, dVACLM_dVd; if ((s->pclm > 0.0) && (diffVds > 1.0e-10)) { double T0 = 1.0 / (s->pclm * Abulk * s->litl); double dT0_dVb = -T0 / Abulk * dAbulk_dVb; double dT0_dVg = -T0 / Abulk * dAbulk_dVg; double T2 = d->vgst / EsatL; double T1 = s->leff * (Abulk + T2); double dT1_dVg = s->leff * ((1.0-T2*dEsatL_dVg)/EsatL + dAbulk_dVg); double dT1_dVb = s->leff * (dAbulk_dVb - T2 * dEsatL_dVb / EsatL); double dT1_dVd = -T2 * dEsatL_dVd / Esat; double T9 = T0 * T1; VACLM = T9 * diffVds; dVACLM_dVg = T0 * dT1_dVg * diffVds - T9 * dVdseff_dVg + T1 * diffVds * dT0_dVg; dVACLM_dVb = (dT0_dVb*T1 + T0*dT1_dVb) * diffVds - T9 * dVdseff_dVb; dVACLM_dVd = T0 * dT1_dVd * diffVds + T9 * (1.0 - dVdseff_dVd); }else{ VACLM = MAX_EXP; dVACLM_dVd = dVACLM_dVg = dVACLM_dVb = 0.0; } trace4("", VACLM, dVACLM_dVg, dVACLM_dVb, dVACLM_dVd); /* Calculate VADIBL */ double VADIBL, dVADIBL_dVg, dVADIBL_dVb, dVADIBL_dVd; if (t->thetaRout > 0.0) { double T8 = Abulk * Vdsat; double T0 = Vgst2Vtm * T8; double dT0_dVg = Vgst2Vtm * Abulk * dVdsat_dVg + T8 + Vgst2Vtm * Vdsat * dAbulk_dVg; double dT0_dVb = Vgst2Vtm * (dAbulk_dVb*Vdsat + Abulk*dVdsat_dVb); double dT0_dVd = Vgst2Vtm * Abulk * dVdsat_dVd; double T1 = Vgst2Vtm + T8; double dT1_dVg = 1.0 + Abulk * dVdsat_dVg + Vdsat * dAbulk_dVg; double dT1_dVb = Abulk * dVdsat_dVb + dAbulk_dVb * Vdsat; double dT1_dVd = Abulk * dVdsat_dVd; double T9 = T1 * T1; double T2 = t->thetaRout; VADIBL = (Vgst2Vtm - T0 / T1) / T2; dVADIBL_dVg = (1.0 - dT0_dVg / T1 + T0 * dT1_dVg / T9) / T2; dVADIBL_dVb = (-dT0_dVb / T1 + T0 * dT1_dVb / T9) / T2; dVADIBL_dVd = (-dT0_dVd / T1 + T0 * dT1_dVd / T9) / T2; double T7 = s->pdiblb * Vbseff; if (T7 >= -0.9) { double T3 = 1.0 / (1.0 + T7); VADIBL *= T3; dVADIBL_dVg *= T3; dVADIBL_dVb = (dVADIBL_dVb - VADIBL * s->pdiblb) * T3; dVADIBL_dVd *= T3; }else{ /* Added to avoid the discontinuity problem caused by pdiblcb */ double T4 = 1.0 / (0.8 + T7); double T3 = (17.0 + 20.0 * T7) * T4; dVADIBL_dVg *= T3; dVADIBL_dVb = dVADIBL_dVb * T3 - VADIBL * s->pdiblb * T4 * T4; dVADIBL_dVd *= T3; VADIBL *= T3; } }else{ VADIBL = MAX_EXP; dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = 0.0; } trace4("", VADIBL, dVADIBL_dVg, dVADIBL_dVb, dVADIBL_dVd); /* Calculate VA */ double T8 = s->pvag / EsatL; double T9 = T8 * d->vgst; double T0, dT0_dVg, dT0_dVb, dT0_dVd; if (T9 > -0.9) { T0 = 1.0 + T9; dT0_dVg = T8 * (1.0 - d->vgst * dEsatL_dVg / EsatL); dT0_dVb = -T9 * dEsatL_dVb / EsatL; dT0_dVd = -T9 * dEsatL_dVd / EsatL; }else{ /* Added to avoid the discontinuity problems caused by pvag */ double T1 = 1.0 / (17.0 + 20.0 * T9); T0 = (0.8 + T9) * T1; T1 *= T1; dT0_dVg = T8 * (1.0 - d->vgst * dEsatL_dVg / EsatL) * T1; T9 *= T1 / EsatL; dT0_dVb = -T9 * dEsatL_dVb; dT0_dVd = -T9 * dEsatL_dVd; } double tmp1 = VACLM * VACLM; double tmp2 = VADIBL * VADIBL; double tmp3 = VACLM + VADIBL; double T1 = VACLM * VADIBL / tmp3; tmp3 *= tmp3; double dT1_dVg = (tmp1 * dVADIBL_dVg + tmp2 * dVACLM_dVg) / tmp3; double dT1_dVd = (tmp1 * dVADIBL_dVd + tmp2 * dVACLM_dVd) / tmp3; double dT1_dVb = (tmp1 * dVADIBL_dVb + tmp2 * dVACLM_dVb) / tmp3; Va = Vasat + T0 * T1; dVa_dVg = dVasat_dVg + T1 * dT0_dVg + T0 * dT1_dVg; dVa_dVd = dVasat_dVd + T1 * dT0_dVd + T0 * dT1_dVd; dVa_dVb = dVasat_dVb + T1 * dT0_dVb + T0 * dT1_dVb; } trace4("", Va, dVa_dVg, dVa_dVd, dVa_dVb); double Idl, dIdl_dVg, dIdl_dVd, dIdl_dVb; { double gche, dgche_dVg, dgche_dVd, dgche_dVb; { double beta, dbeta_dVg, dbeta_dVd, dbeta_dVb; { double CoxWovL = m->cox * Weff / s->leff; beta = ueff * CoxWovL; dbeta_dVg = CoxWovL * dueff_dVg + beta * dWeff_dVg / Weff; dbeta_dVd = CoxWovL * dueff_dVd; dbeta_dVb = CoxWovL * dueff_dVb + beta * dWeff_dVb / Weff; } trace4("", beta, dbeta_dVg, dbeta_dVd, dbeta_dVb); double fgche1, dfgche1_dVg, dfgche1_dVd, dfgche1_dVb; { double T0 = 1.0 - 0.5 * Abulk * Vdseff / Vgst2Vtm; double dT0_dVg = -0.5 * (Abulk * dVdseff_dVg - Abulk * Vdseff / Vgst2Vtm + Vdseff * dAbulk_dVg) / Vgst2Vtm; double dT0_dVd = -0.5 * Abulk * dVdseff_dVd / Vgst2Vtm; double dT0_dVb = -0.5 * (Abulk*dVdseff_dVb + dAbulk_dVb*Vdseff) / Vgst2Vtm; fgche1 = d->vgst * T0; dfgche1_dVg = d->vgst * dT0_dVg + T0; dfgche1_dVd = d->vgst * dT0_dVd; dfgche1_dVb = d->vgst * dT0_dVb; } trace4("", fgche1, dfgche1_dVg, dfgche1_dVd, dfgche1_dVb); double fgche2, dfgche2_dVg, dfgche2_dVd, dfgche2_dVb; { double T9 = Vdseff / EsatL; fgche2 = 1.0 + T9; dfgche2_dVg = (dVdseff_dVg - T9 * dEsatL_dVg) / EsatL; dfgche2_dVd = (dVdseff_dVd - T9 * dEsatL_dVd) / EsatL; dfgche2_dVb = (dVdseff_dVb - T9 * dEsatL_dVb) / EsatL; } trace4("", fgche2, dfgche2_dVg, dfgche2_dVd, dfgche2_dVb); gche = beta * fgche1 / fgche2; dgche_dVg = (beta * dfgche1_dVg + fgche1 * dbeta_dVg - gche * dfgche2_dVg) / fgche2; dgche_dVd = (beta * dfgche1_dVd + fgche1 * dbeta_dVd - gche * dfgche2_dVd) / fgche2; dgche_dVb = (beta * dfgche1_dVb + fgche1 * dbeta_dVb - gche * dfgche2_dVb) / fgche2; } trace4("", gche, dgche_dVg, dgche_dVd, dgche_dVb); double T0 = 1.0 + gche * Rds; double T9 = Vdseff / T0; Idl = gche * T9; dIdl_dVg = (gche * dVdseff_dVg + T9 * dgche_dVg) / T0 - Idl * gche / T0 * dRds_dVg; dIdl_dVd = (gche * dVdseff_dVd + T9 * dgche_dVd) / T0; dIdl_dVb = (gche*dVdseff_dVb + T9*dgche_dVb - Idl*dRds_dVb*gche) / T0; } trace4("", Idl, dIdl_dVg, dIdl_dVd, dIdl_dVb); double T9 = diffVds / Va; double T0 = 1.0 + T9; Idsa = Idl * T0; dIdsa_dVg = T0 * dIdl_dVg - Idl * (dVdseff_dVg + T9 * dVa_dVg) / Va; dIdsa_dVd = T0 * dIdl_dVd + Idl * (1.0 - dVdseff_dVd - T9*dVa_dVd) / Va; dIdsa_dVb = T0 * dIdl_dVb - Idl * (dVdseff_dVb + T9 * dVa_dVb) / Va; } trace4("", Idsa, dIdsa_dVg, dIdsa_dVd, dIdsa_dVb); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // d->ids, d->gds, d->gmf, d->gmbf { double VASCBE, dVASCBE_dVg, dVASCBE_dVd, dVASCBE_dVb; if (s->pscbe2 > 0.0) { if (diffVds > s->pscbe1 * s->litl / EXP_THRESHOLD) { double T0 = s->pscbe1 * s->litl / diffVds; VASCBE = s->leff * exp(T0) / s->pscbe2; double T1 = T0 * VASCBE / diffVds; dVASCBE_dVg = T1 * dVdseff_dVg; dVASCBE_dVd = -T1 * (1.0 - dVdseff_dVd); dVASCBE_dVb = T1 * dVdseff_dVb; }else{ VASCBE = MAX_EXP * s->leff/s->pscbe2; dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0; } }else{ VASCBE = MAX_EXP; dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0; } double T9 = diffVds / VASCBE; double T0 = 1.0 + T9; double Ids = Idsa * T0; double Gm = T0*dIdsa_dVg - Idsa*(dVdseff_dVg + T9*dVASCBE_dVg) / VASCBE; double Gds = T0 * dIdsa_dVd + Idsa * (1.0 - dVdseff_dVd - T9 * dVASCBE_dVd) / VASCBE; double Gmb = T0 * dIdsa_dVb - Idsa * (dVdseff_dVb + T9 * dVASCBE_dVb) / VASCBE; trace3("", T0, dIdsa_dVb, (T0 * dIdsa_dVb)); trace4("", dVdseff_dVb, T9, dVASCBE_dVb, (dVdseff_dVb + T9*dVASCBE_dVb)); trace3("", Idsa, VASCBE, (Idsa*(dVdseff_dVb+T9*dVASCBE_dVb)/VASCBE)); Gds += Gm * dVgsteff_dVd; Gmb += Gm * dVgsteff_dVb; Gm *= dVgsteff_dVg; Gmb *= dVbseff_dVb; trace4("", Ids, Gm, Gds, Gmb); trace0("========================="); d->gds = Gds; if (d->reversed) { d->ids = -Ids; d->gmr = Gm; d->gmbr = Gmb; d->gmf = d->gmbf = 0; }else{ d->ids = Ids; d->gmf = Gm; d->gmbf = Gmb; d->gmr = d->gmbr = 0.; } } trace4("", d->ids, d->gds, d->gmf, d->gmbf); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // d->isub, d->gbbs, d->gbgs, d->gbds { /* calculate substrate current Isub */ double Isub, Gbd, Gbb, Gbg; double tmp = s->alpha0 + s->alpha1 * s->leff; if ((tmp <= 0.0) || (s->beta0 <= 0.0)) { Isub = Gbd = Gbb = Gbg = 0.0; trace4("no-isub", Isub, Gbd, Gbb, Gbg); }else{ double T2 = tmp / s->leff; double T1, dT1_dVg, dT1_dVd, dT1_dVb; if (diffVds > s->beta0 / EXP_THRESHOLD) { double T0 = -s->beta0 / diffVds; T1 = T2 * diffVds * exp(T0); double T3 = T1 / diffVds * (T0 - 1.0); trace3("", T0, T2, T3); dT1_dVg = T3 * dVdseff_dVg; dT1_dVd = T3 * (dVdseff_dVd - 1.0); dT1_dVb = T3 * dVdseff_dVb; trace4("vds > ?", T1, dT1_dVg, dT1_dVd, dT1_dVb); }else{ double T3 = T2 * MIN_EXP; trace2("", T2, T3); T1 = T3 * diffVds; dT1_dVg = -T3 * dVdseff_dVg; dT1_dVd = T3 * (1.0 - dVdseff_dVd); dT1_dVb = -T3 * dVdseff_dVb; trace4("vds < ?", T1, dT1_dVg, dT1_dVd, dT1_dVb); } Isub = T1 * Idsa; Gbg = T1 * dIdsa_dVg + Idsa * dT1_dVg; Gbd = T1 * dIdsa_dVd + Idsa * dT1_dVd; Gbb = T1 * dIdsa_dVb + Idsa * dT1_dVb; trace4("raw", Isub, Gbd, Gbb, Gbg); Gbd += Gbg * dVgsteff_dVd; Gbb += Gbg * dVgsteff_dVb; Gbg *= dVgsteff_dVg; Gbb *= dVbseff_dVb; /* bug fixing */ } trace4("", Isub, Gbd, Gbb, Gbg); if (!(d->reversed)) { d->idb = Isub; d->gdbds = Gbd; d->gdbgs = Gbg; d->gdbbs = Gbb; d->isb = d->gsbsd = d->gsbgd = d->gsbbd = 0.; }else{ d->idb = d->gdbds = d->gdbgs = d->gdbbs = 0.; d->isb = Isub; d->gsbsd = Gbd; d->gsbgd = Gbg; d->gsbbd = Gbb; } //double d__csub = Isub - (Gbb * Vbseff + Gbd * d->vds + Gbg * d->vgs); } trace4("", d->isub, d->gbbs, d->gbgs, d->gbds); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Calculate Qinv for Noise analysis */ { // from 3.1 //double T1 = d->vgst * (1.0 - 0.5 * Abulk * Vdseff / Vgst2Vtm); //double d__qinv = -m->cox * Weff * s->leff * T1; // from 3.3 // /* BSIM3 thermal noise Qinv calculated from all capMod // 0, 1, 2 & 3 stored in here->BSIM3qinv 1/1998 */ } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ends line 2020 (finished) // d->qgate, d->qdrn, d->qbulk // d->cggb, d->cgsb, d->cgdb // d->cdgb, d->cdsb, d->cddb // d->cbgb, d->cbsb, d->cbdb assert(d->qbulk == d->qbulk); assert(d->qdrn == d->qdrn); assert(d->qgate == d->qgate); { const bool ChargeComputationNeeded = true; trace2("", m->xpart, m->capMod); if ((m->xpart < 0) || (!ChargeComputationNeeded)) { d->qgate = d->qdrn = d->qbulk = 0.0; d->cggb = d->cgsb = d->cgdb = 0.0; d->cdgb = d->cdsb = d->cddb = 0.0; d->cbgb = d->cbsb = d->cbdb = 0.0; ////////// d->cqdb = d->cqsb = d->cqgb = d->cqbb = 0.0; ////////// d->gtau = 0.0; trace0("xpart < 0 || no charge computation"); untested(); assert(d->qbulk == d->qbulk); assert(d->qdrn == d->qdrn); assert(d->qgate == d->qgate); untested(); }else if (m->capMod == 0) { untested(); // block ends 1876 this 1599 trace0("begin capMod == 0 (mos8)"); if (Vbseff < 0.0) { // redefinition Vbseff = d->vbs; dVbseff_dVb = 1.0; }else{ Vbseff = t->phi - Phis; dVbseff_dVb = -dPhis_dVb; } trace1("old value replaced", dVth_dVb); double Vfb = s->vfbcv; // possible improper redefinition later double Vth = Vfb + t->phi + t->k1ox * sqrtPhis; dVth_dVb = t->k1ox * dsqrtPhis_dVb; // redefinition double Vgst = Vgs_eff - Vth; //double dVgst_dVb = -dVth_dVb; //double dVgst_dVg = dVgs_eff_dVg; double CoxWL = m->cox * s->weffCV * s->leffCV; double Arg1 = Vgs_eff - Vbseff - Vfb; trace3("", Vfb, Vth, dVth_dVb); trace3("", Vgst, CoxWL, Arg1); // ends 1618 this 1328 if (Arg1 <= 0.0) { trace0("Arg1 <= 0.0"); d->qgate = CoxWL * Arg1; d->cggb = CoxWL * dVgs_eff_dVg; d->cgdb = 0.0; d->cgsb = CoxWL * (dVbseff_dVb - dVgs_eff_dVg); d->qbulk = -d->qgate; d->cbgb = -CoxWL * dVgs_eff_dVg; d->cbdb = 0.0; d->cbsb = -d->cgsb; d->qdrn = 0.0; d->cdgb = 0.0; d->cddb = 0.0; d->cdsb = 0.0; ////////// d->qinv = 0.0; }else if (Vgst <= 0.0) { trace0("Vgst <= 0.0"); double T1 = 0.5 * t->k1ox; double T2 = sqrt(T1 * T1 + Arg1); double T0 = CoxWL * T1 / T2; d->qgate = CoxWL * t->k1 * (T2 - T1); d->cggb = T0 * dVgs_eff_dVg; d->cgdb = 0.0; d->cgsb = T0 * (dVbseff_dVb - dVgs_eff_dVg); d->qbulk = -d->qgate; d->cbgb = -d->cggb; d->cbdb = 0.0; d->cbsb = -d->cgsb; d->qdrn = 0.0; d->cdgb = 0.0; d->cddb = 0.0; d->cdsb = 0.0; }else{ trace0("!(Arg1 <= 0.0 || Vgst <= 0.0)"); double One_Third_CoxWL = CoxWL / 3.0; double Two_Third_CoxWL = 2.0 * One_Third_CoxWL; // redefine Vdsat, dVdsat_dVg, dVdsat_dVb { double AbulkCV = Abulk0 * s->abulkCVfactor; double dAbulkCV_dVb = s->abulkCVfactor * dAbulk0_dVb; Vdsat = Vgst / AbulkCV; dVdsat_dVg = dVgs_eff_dVg / AbulkCV; dVdsat_dVb = - (Vdsat * dAbulkCV_dVb + dVth_dVb)/ AbulkCV; } if (m->xpart > 0.5) { /* 0/100 Charge partition model */ if (d->vds >= Vdsat) { /* saturation region */ double T1 = Vdsat / 3.0; double T2 = -One_Third_CoxWL * dVdsat_dVb; d->qgate = CoxWL * (Vgs_eff - Vfb - t->phi - T1); d->cggb = One_Third_CoxWL * (3.0 - dVdsat_dVg) * dVgs_eff_dVg; d->cgsb = -(d->cggb + T2); d->cgdb = 0.0; double T2a = -Two_Third_CoxWL * Vgst; double T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); d->qbulk = -(d->qgate + T2a); d->cbgb = -(d->cggb - Two_Third_CoxWL * dVgs_eff_dVg); d->cbsb = -(d->cbgb + T3); d->cbdb = 0.0; d->qdrn = 0.0; d->cdgb = 0.0; d->cddb = 0.0; d->cdsb = 0.0; ////////// d->qinv = -(d->qgate + d->qbulk); }else{ /* linear region */ double Alphaz = Vgst / Vdsat; double T1 = 2.0 * Vdsat - d->vds; double T2 = d->vds / (3.0 * T1); double T3 = T2 * d->vds; double T9 = 0.25 * CoxWL; double T4 = T9 * Alphaz; double T7 = 2.0 * d->vds - T1 - 3.0 * T3; double T8 = T3 - T1 - 2.0 * d->vds; d->qgate = CoxWL * (Vgs_eff - Vfb - t->phi - 0.5 * (d->vds-T3)); double T10 = T4 * T8; d->qdrn = T4 * T7; d->qbulk = -(d->qgate + d->qdrn + T10); ////////// d->qinv = -(d->qgate + d->qbulk); double T5 = T3 / T1; d->cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg; double T11 = -CoxWL * T5 * dVdsat_dVb; d->cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5); d->cgsb = -(d->cggb + T11 + d->cgdb); double T6 = 1.0 / Vdsat; double dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg); double dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb); T7 = T9 * T7; T8 = T9 * T8; T9 = 2.0 * T4 * (1.0 - 3.0 * T5); d->cdgb = (T7 * dAlphaz_dVg - T9 * dVdsat_dVg) * dVgs_eff_dVg; double T12 = T7 * dAlphaz_dVb - T9 * dVdsat_dVb; d->cddb = T4 * (3.0 - 6.0 * T2 - 3.0 * T5); d->cdsb = -(d->cdgb + T12 + d->cddb); T9 = 2.0 * T4 * (1.0 + T5); T10 = (T8 * dAlphaz_dVg - T9 * dVdsat_dVg) * dVgs_eff_dVg; T11 = T8 * dAlphaz_dVb - T9 * dVdsat_dVb; T12 = T4 * (2.0 * T2 + T5 - 1.0); double T0 = -(T10 + T11 + T12); d->cbgb = -(d->cggb + d->cdgb + T10); d->cbdb = -(d->cgdb + d->cddb + T12); d->cbsb = -(d->cgsb + d->cdsb + T0); } }else if (m->xpart < 0.5) { /* 40/60 Charge partition model */ if (d->vds >= Vdsat) { /* saturation region */ double T1 = Vdsat / 3.0; d->qgate = CoxWL * (Vgs_eff - Vfb - t->phi - T1); double T2 = -Two_Third_CoxWL * Vgst; d->qbulk = -(d->qgate + T2); d->qdrn = 0.4 * T2; ////////// d->qinv = -(d->qgate + d->qbulk); d->cggb = One_Third_CoxWL * (3.0 - dVdsat_dVg) * dVgs_eff_dVg; T2 = -One_Third_CoxWL * dVdsat_dVb; d->cgsb = -(d->cggb + T2); d->cgdb = 0.0; double T3 = 0.4 * Two_Third_CoxWL; d->cdgb = -T3 * dVgs_eff_dVg; d->cddb = 0.0; double T4 = T3 * dVth_dVb; d->cdsb = -(T4 + d->cdgb); d->cbgb = -(d->cggb - Two_Third_CoxWL * dVgs_eff_dVg); T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); d->cbsb = -(d->cbgb + T3); d->cbdb = 0.0; }else{ /* linear region */ double T1 = 2.0 * Vdsat - d->vds; double T2 = d->vds / (3.0 * T1); double T3 = T2 * d->vds; d->qgate = CoxWL * (Vgs_eff - Vfb - t->phi - 0.5 * (d->vds - T3)); double T5 = T3 / T1; d->cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg; double tmp = -CoxWL * T5 * dVdsat_dVb; d->cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5); d->cgsb = -(d->cggb + d->cgdb + tmp); double T6 = 1.0 / Vdsat; double Alphaz = T6 * Vgst; double dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg); double dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb); T6 = 8.0 * Vdsat * Vdsat - 6.0 * Vdsat * d->vds + 1.2 * d->vds * d->vds; double T8 = T2 / T1; double T7 = d->vds - T1 - T8 * T6; double T9 = 0.25 * CoxWL; double T4 = T9 * Alphaz; d->qdrn = T4 * T7; T7 *= T9; tmp = T8 / T1; double tmp1 = T4 * (2.0 - 4.0 * tmp * T6 + T8 * (16.0 * Vdsat - 6.0 * d->vds)); d->cdgb = (T7 * dAlphaz_dVg - tmp1 * dVdsat_dVg) * dVgs_eff_dVg; double T10 = T7 * dAlphaz_dVb - tmp1 * dVdsat_dVb; d->cddb = T4 * (2.0 - (1.0 / (3.0 * T1 * T1) + 2.0 * tmp) * T6 + T8 * (6.0 * Vdsat - 2.4 * d->vds)); d->cdsb = -(d->cdgb + T10 + d->cddb); T7 = 2.0 * (T1 + T3); d->qbulk = -(d->qgate - T4 * T7); T7 *= T9; double T0 = 4.0 * T4 * (1.0 - T5); double T12 = (-T7 * dAlphaz_dVg - d->cdgb - T0 * dVdsat_dVg) * dVgs_eff_dVg; double T11 = -T7 * dAlphaz_dVb - T10 - T0 * dVdsat_dVb; T10 = -4.0 * T4 * (T2 - 0.5 + 0.5 * T5) - d->cddb; tmp = -(T10 + T11 + T12); d->cbgb = -(d->cggb + d->cdgb + T12); d->cbdb = -(d->cgdb + d->cddb + T10); /* bug fix 3.3 */ d->cbsb = -(d->cgsb + d->cdsb + tmp); trace3("0,40/60,lin", T10, T11, T12); trace3("0,40/60,lin", d->cbgb, d->cbdb, d->cbsb); ////////// d->qinv = -(d->qgate + d->qbulk); } }else{ /* 50/50 partitioning */ if (d->vds >= Vdsat) { /* saturation region */ double T1 = Vdsat / 3.0; d->qgate = CoxWL * (Vgs_eff - Vfb - t->phi - T1); double T2 = -Two_Third_CoxWL * Vgst; d->qbulk = -(d->qgate + T2); ////////// d->qinv = -(d->qgate + d->qbulk); d->qdrn = 0.5 * T2; T2 = -One_Third_CoxWL * dVdsat_dVb; d->cggb = One_Third_CoxWL * (3.0 - dVdsat_dVg) * dVgs_eff_dVg; d->cgsb = -(d->cggb + T2); d->cgdb = 0.0; double T4 = One_Third_CoxWL * dVth_dVb; d->cdgb = -One_Third_CoxWL * dVgs_eff_dVg; d->cddb = 0.0; d->cdsb = -(T4 + d->cdgb); double T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); d->cbgb = -(d->cggb - Two_Third_CoxWL * dVgs_eff_dVg); d->cbsb = -(d->cbgb + T3); d->cbdb = 0.0; }else{ /* linear region */ double T1 = 2.0 * Vdsat - d->vds; double T2 = d->vds / (3.0 * T1); double T3 = T2 * d->vds; double T5 = T3 / T1; double tmp = -CoxWL * T5 * dVdsat_dVb; d->qgate = CoxWL * (Vgs_eff - Vfb - t->phi - 0.5 * (d->vds-T3)); d->cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg; d->cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5); d->cgsb = -(d->cggb + d->cgdb + tmp); double T6 = 1.0 / Vdsat; double Alphaz = T6 * Vgst; double dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg); double dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb); double T9 = 0.25 * CoxWL; double T4 = T9 * Alphaz; double T7 = T1 + T3; d->qdrn = -T4 * T7; d->qbulk = - (d->qgate + d->qdrn + d->qdrn); ////////// d->qinv = -(d->qgate + d->qbulk); T7 *= T9; double T0 = T4 * (2.0 * T5 - 2.0); double T12 = T0 * dVdsat_dVb - T7 * dAlphaz_dVb; d->cdgb = (T0 * dVdsat_dVg - T7 * dAlphaz_dVg) * dVgs_eff_dVg; d->cddb = T4 * (1.0 - 2.0 * T2 - T5); d->cdsb = -(d->cdgb + T12 + d->cddb); d->cbgb = -(d->cggb + 2.0 * d->cdgb); d->cbdb = -(d->cgdb + 2.0 * d->cddb); d->cbsb = -(d->cgsb + 2.0 * d->cdsb); } } } // begins 1328 this 1618 trace0("end capMod == 0"); // end of else if (m->capMod == 0) line 1598 this 1875 untested(); assert(d->qbulk == d->qbulk); assert(d->qdrn == d->qdrn); assert(d->qgate == d->qgate); untested(); }else{ trace0("begin capMod != 0 (mos8)"); assert(m->capMod != 0); double qsrc; double VbseffCV, dVbseffCV_dVb; if (Vbseff < 0.0) { VbseffCV = Vbseff; dVbseffCV_dVb = 1.0; }else{ VbseffCV = t->phi - Phis; dVbseffCV_dVb = -dPhis_dVb; } trace2("", VbseffCV, dVbseffCV_dVb); //////////-----------moved??? //double Vth = d->von; // possibly wrong value -- scope problem //double Vfb = Vth - t->phi - t->k1 * sqrtPhis; //double dVfb_dVb = dVth_dVb - t->k1 * dsqrtPhis_dVb; //double dVfb_dVd = dVth_dVd; //////////-------------end moved? double Vgsteff; { /* Seperate VgsteffCV with noff and voffcv */ double nnoff = n * s->noff; double dnoff_dVd = s->noff * dn_dVd; double dnoff_dVb = s->noff * dn_dVb; double T0 = t->vtm * nnoff; double Vgst = Vgs_eff - d->von; double VgstNVt = (Vgst - s->voffcv) / (2*T0); trace3("", d->vgst, Vgst, VgstNVt); trace2("", n, t->vtm); if (VgstNVt > EXP_THRESHOLD) { trace0("VgstNVt above"); Vgsteff = Vgst - s->voffcv; dVgsteff_dVg = dVgs_eff_dVg; dVgsteff_dVd = -dVth_dVd; dVgsteff_dVb = -dVth_dVb; }else if (VgstNVt < -EXP_THRESHOLD) { trace0("VgstNVt below"); Vgsteff = T0 * log(1.0 + MIN_EXP); dVgsteff_dVg = 0.0; dVgsteff_dVd = Vgsteff / nnoff; dVgsteff_dVb = dVgsteff_dVd * dnoff_dVb; dVgsteff_dVd *= dnoff_dVd; }else{ trace0("VgstNVt in range"); double ExpVgst = exp(VgstNVt); trace1("", ExpVgst); Vgsteff = T0 * log(1.0 + ExpVgst); dVgsteff_dVg = ExpVgst / (1.0 + ExpVgst); dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + (Vgst - s->voffcv) / nnoff * dnoff_dVd) + Vgsteff / nnoff * dnoff_dVd; dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + (Vgst - s->voffcv) / nnoff * dnoff_dVb) + Vgsteff / nnoff * dnoff_dVb; dVgsteff_dVg *= dVgs_eff_dVg; } /* End of VgsteffCV */ } trace4("", Vgsteff, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb); /* old code if ((VgstNVt > -EXP_THRESHOLD) && (VgstNVt < EXP_THRESHOLD)) { assert(ExpVgst != NOT_VALID); ExpVgst *= ExpVgst; Vgsteff = n * t->vtm * log(1.0 + ExpVgst); dVgsteff_dVg = ExpVgst / (1.0 + ExpVgst); dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + (Vgs_eff-Vth)/n * dn_dVd) + Vgsteff/n * dn_dVd; dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + (Vgs_eff-Vth)/n * dn_dVb) + Vgsteff/n * dn_dVb; dVgsteff_dVg *= dVgs_eff_dVg; }else{ Vgsteff = d->vgst; } */ double CoxWL = m->cox * s->weffCV * s->leffCV; // redundant?? if (m->capMod == 1) { untested(); double Cgg, Cgd, Cgb; { double Vfb = t->vfbzb; double Arg1 = Vgs_eff - VbseffCV - Vfb - Vgsteff; if (Arg1 <= 0.0) { d->qgate = CoxWL * Arg1; Cgg = CoxWL * (dVgs_eff_dVg - dVgsteff_dVg); //Cgd = -CoxWL * (dVfb_dVd + dVgsteff_dVd); //Cgb = -CoxWL * (dVfb_dVb + dVbseffCV_dVb + dVgsteff_dVb); Cgd = -CoxWL * dVgsteff_dVd; Cgb = -CoxWL * (dVbseffCV_dVb + dVgsteff_dVb); }else{ double T0 = 0.5 * t->k1ox; double T1 = sqrt(T0 * T0 + Arg1); double T2 = CoxWL * T0 / T1; d->qgate = CoxWL * t->k1ox * (T1 - T0); Cgg = T2 * (dVgs_eff_dVg - dVgsteff_dVg); //Cgd = -T2 * (dVfb_dVd + dVgsteff_dVd); //Cgb = -T2 * (dVfb_dVb + dVbseffCV_dVb + dVgsteff_dVb); Cgd = -T2 * dVgsteff_dVd; Cgb = -T2 * (dVbseffCV_dVb + dVgsteff_dVb); } } d->qbulk = -d->qgate; double Cbg = -Cgg; double Cbd = -Cgd; double Cbb = -Cgb; double AbulkCV = Abulk0 * s->abulkCVfactor; double dAbulkCV_dVb = s->abulkCVfactor * dAbulk0_dVb; double Csg, Csb, Csd; { double VdsatCV = Vgsteff / AbulkCV; if (VdsatCV < d->vds) { double One_Third_CoxWL = CoxWL / 3.0; double Two_Third_CoxWL = 2.0 * One_Third_CoxWL; double dVdsatCV_dVg = 1.0 / AbulkCV; double dVdsatCV_dVb = -VdsatCV * dAbulkCV_dVb / AbulkCV; { double T0 = Vgsteff - VdsatCV / 3.0; double dT0_dVg = 1.0 - dVdsatCV_dVg / 3.0; double dT0_dVb = -dVdsatCV_dVb / 3.0; d->qgate += CoxWL * T0; double Cgg1 = CoxWL * dT0_dVg; double Cgb1 = CoxWL * dT0_dVb + Cgg1 * dVgsteff_dVb; double Cgd1 = Cgg1 * dVgsteff_dVd; Cgg1 *= dVgsteff_dVg; Cgg += Cgg1; Cgb += Cgb1; Cgd += Cgd1; } { double T0 = VdsatCV - Vgsteff; double dT0_dVg = dVdsatCV_dVg - 1.0; double dT0_dVb = dVdsatCV_dVb; d->qbulk += One_Third_CoxWL * T0; double Cbg1 = One_Third_CoxWL * dT0_dVg; double Cbb1 = One_Third_CoxWL * dT0_dVb + Cbg1 * dVgsteff_dVb; double Cbd1 = Cbg1 * dVgsteff_dVd; Cbg1 *= dVgsteff_dVg; Cbg += Cbg1; Cbb += Cbb1; Cbd += Cbd1; } double T0; if (m->xpart > 0.5) { T0 = -Two_Third_CoxWL; }else if (m->xpart < 0.5) { T0 = -0.4 * CoxWL; }else{ T0 = -One_Third_CoxWL; } qsrc = T0 * Vgsteff; Csg = T0 * dVgsteff_dVg; Csb = T0 * dVgsteff_dVb; Csd = T0 * dVgsteff_dVd; Cgb *= dVbseff_dVb; Cbb *= dVbseff_dVb; Csb *= dVbseff_dVb; }else{ double T0 = AbulkCV * d->vds; double T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1.e-20); double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1; { double T2 = d->vds / T1; double T3 = T0 * T2; double dT3_dVg = -12.0 * T2 * T2 * AbulkCV; double dT3_dVd = 6.0 * T0 * (4.0*Vgsteff - T0) / T1 / T1 - 0.5; double dT3_dVb = 12.0 * T2 * T2 * dAbulkCV_dVb * Vgsteff; d->qgate += CoxWL * (Vgsteff - 0.5 * d->vds + T3); Cgg1 = CoxWL * (1.0 + dT3_dVg); Cgb1 = CoxWL * dT3_dVb + Cgg1 * dVgsteff_dVb; Cgd1 = CoxWL * dT3_dVd + Cgg1 * dVgsteff_dVd; Cgg1 *= dVgsteff_dVg; Cgg += Cgg1; Cgb += Cgb1; Cgd += Cgd1; d->qbulk += CoxWL * (1.0 - AbulkCV) * (0.5 * d->vds - T3); Cbg1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVg); Cbb1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVb + (0.5 * d->vds - T3) * dAbulkCV_dVb) + Cbg1 * dVgsteff_dVb; Cbd1 = -CoxWL * (1.0 - AbulkCV) * dT3_dVd + Cbg1 * dVgsteff_dVd; Cbg1 *= dVgsteff_dVg; Cbg += Cbg1; Cbb += Cbb1; Cbd += Cbd1; } if (m->xpart > 0.5) { /* 0/100 Charge petition model */ T1 = T1 + T1; qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 - T0 * T0 / T1); Csg = -CoxWL * (0.5 + 24.0 * T0 * d->vds / T1 / T1 * AbulkCV); Csb = -CoxWL * (0.25 * d->vds * dAbulkCV_dVb - 12.0 * T0 * d->vds / T1 / T1 * (4.0 * Vgsteff - T0) * dAbulkCV_dVb) + Csg * dVgsteff_dVb; Csd = -CoxWL * (0.25 * AbulkCV - 12.0 * AbulkCV * T0 / T1 / T1 * (4.0 * Vgsteff - T0)) + Csg * dVgsteff_dVd; Csg *= dVgsteff_dVg; }else if (m->xpart < 0.5) { /* 40/60 Charge petition model */ T1 = T1 / 12.0; double T2 = 0.5 * CoxWL / (T1 * T1); double T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff * (Vgsteff - 4.0 * T0 / 3.0)) - 2.0 * T0 * T0 * T0 / 15.0; qsrc = -T2 * T3; double T4 = 4.0 / 3.0 * Vgsteff * (Vgsteff-T0) + 0.4 * T0 * T0; Csg = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0 * Vgsteff - 8.0 * T0 / 3.0) + 2.0 * T0 * T0 / 3.0); Csb = (qsrc / T1 * d->vds + T2 * T4 * d->vds) * dAbulkCV_dVb + Csg * dVgsteff_dVb; Csd = (qsrc / T1 + T2 * T4) * AbulkCV + Csg * dVgsteff_dVd; Csg *= dVgsteff_dVg; }else{ /* 50/50 Charge petition model */ qsrc = -0.5 * (d->qgate + d->qbulk); Csg = -0.5 * (Cgg1 + Cbg1); Csb = -0.5 * (Cgb1 + Cbb1); Csd = -0.5 * (Cgd1 + Cbd1); } Cgb *= dVbseff_dVb; Cbb *= dVbseff_dVb; Csb *= dVbseff_dVb; } } d->qdrn = -(d->qgate + d->qbulk + qsrc); d->cggb = Cgg; d->cgsb = -(Cgg + Cgd + Cgb); d->cgdb = Cgd; d->cdgb = -(Cgg + Cbg + Csg); d->cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb); d->cddb = -(Cgd + Cbd + Csd); d->cbgb = Cbg; d->cbsb = -(Cbg + Cbd + Cbb); d->cbdb = Cbd; ////////// d->qinv = -(d->qgate + d->qbulk); trace0("end capMod == 1"); untested(); assert(d->qbulk == d->qbulk); assert(d->qdrn == d->qdrn); assert(d->qgate == d->qgate); untested(); }else if (m->capMod == 2) { trace0("begin capMod == 2"); double Qac0, dQac0_dVg, dQac0_dVb; double Qsub0, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb; { double Vfb = t->vfbzb; double Vfbeff, dVfbeff_dVg, dVfbeff_dVb; { const double DELTA_3 = 0.02; double V3 = Vfb - Vgs_eff + VbseffCV - DELTA_3; double T0; //, T2; if (Vfb <= 0.0) { T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * Vfb); //T2 = -DELTA_3 / T0; }else{ T0 = sqrt(V3 * V3 + 4.0 * DELTA_3 * Vfb); //T2 = DELTA_3 / T0; } double T1 = 0.5 * (1.0 + V3 / T0); Vfbeff = Vfb - 0.5 * (V3 + T0); //dVfbeff_dVd = (1.0 - T1 - T2) * dVfb_dVd; dVfbeff_dVg = T1 * dVgs_eff_dVg; //dVfbeff_dVb = (1.0 - T1 - T2) * dVfb_dVb - T1 * dVbseffCV_dVb; dVfbeff_dVb = -T1 * dVbseffCV_dVb; } trace3("", Vfbeff, dVfbeff_dVg, dVfbeff_dVb); //double Qac0, dQac0_dVg, dQac0_dVd, dQac0_dVb; { Qac0 = CoxWL * (Vfbeff - Vfb); dQac0_dVg = CoxWL * dVfbeff_dVg; //dQac0_dVd = CoxWL * (dVfbeff_dVd - dVfb_dVd); //dQac0_dVb = CoxWL * (dVfbeff_dVb - dVfb_dVb); dQac0_dVb = CoxWL * dVfbeff_dVb; } //double Qsub0, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb; { double T0 = 0.5 * t->k1ox; double T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff; double T1, T2; if (t->k1ox == 0.0) { T1 = 0.0; T2 = 0.0; }else if (T3 < 0.0) { T1 = T0 + T3 / t->k1ox; T2 = CoxWL; }else{ T1 = sqrt(T0 * T0 + T3); T2 = CoxWL * T0 / T1; } Qsub0 = CoxWL * t->k1ox * (T1 - T0); dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg); //dQsub0_dVd = -T2 * (dVfbeff_dVd + dVgsteff_dVd); dQsub0_dVd = -T2 * dVgsteff_dVd; dQsub0_dVb = -T2 * (dVfbeff_dVb +dVbseffCV_dVb +dVgsteff_dVb); } } trace3("", Qac0, dQac0_dVg, dQac0_dVb); trace4("", Qsub0, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb); double AbulkCV = Abulk0 * s->abulkCVfactor; double dAbulkCV_dVb = s->abulkCVfactor * dAbulk0_dVb; trace2("", AbulkCV, dAbulkCV_dVb); double VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb; { const double DELTA_4 = 0.02; double VdsatCV = Vgsteff / AbulkCV; double V4 = VdsatCV - d->vds - DELTA_4; double T0 = sqrt(V4 * V4 + 4.0 * DELTA_4 * VdsatCV); VdseffCV = VdsatCV - 0.5 * (V4 + T0); double T1 = 0.5 * (1.0 + V4 / T0); double T2 = DELTA_4 / T0; double T3 = (1.0 - T1 - T2) / AbulkCV; dVdseffCV_dVg = T3; dVdseffCV_dVd = T1; dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb; /* Added to eliminate non-zero VdseffCV at Vds=0.0 */ if (d->vds == 0.0) { //////VdseffCV = 0.0; //////dVdseffCV_dVg = 0.0; //////dVdseffCV_dVb = 0.0; } } trace4("", VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb); double T0 = AbulkCV * VdseffCV; double T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1e-20); trace2("", T0, T1); double Cgg1, Cgd1, Cgb1, Cbg1, Cbd1, Cbb1; // also 1st estimate of d->qgate, d->qbulk { double T2 = VdseffCV / T1; double T3 = T0 * T2; double T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV); double T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5); double T6 = 12.0 * T2 * T2 * Vgsteff; ////////// double qinoi = -CoxWL * (Vgsteff - 0.5 * T0 + AbulkCV * T3); ////////// d->qinv = qinoi; d->qgate = CoxWL * (Vgsteff - 0.5 * VdseffCV + T3); Cgg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); Cgd1 = CoxWL * T5 * dVdseffCV_dVd + Cgg1 * dVgsteff_dVd; Cgb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Cgg1 * dVgsteff_dVb; Cgg1 *= dVgsteff_dVg; double T7 = 1.0 - AbulkCV; d->qbulk = CoxWL * T7 * (0.5 * VdseffCV - T3); T4 = -T7 * (T4 - 1.0); T5 = -T7 * T5; T6 = -(T7 * T6 + (0.5 * VdseffCV - T3)); Cbg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); Cbd1 = CoxWL * T5 * dVdseffCV_dVd + Cbg1 * dVgsteff_dVd; Cbb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Cbg1 * dVgsteff_dVb; Cbg1 *= dVgsteff_dVg; } trace3("", Cgg1, Cgd1, Cgb1); trace3("", Cbg1, Cbd1, Cbb1); trace2("2-1", d->qgate, d->qbulk); double Csg, Csd, Csb; trace1("", m->xpart); if (m->xpart > 0.5) { trace0("0/100 Charge petition model"); T1 = T1 + T1; qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 - T0 * T0 / T1); double T7 = (4.0 * Vgsteff - T0) / (T1 * T1); double T4 = -(0.5 + 24.0 * T0 * T0 / (T1 * T1)); double T5 = -(0.25 * AbulkCV - 12.0 * AbulkCV * T0 * T7); double T6 = -(0.25 * VdseffCV - 12.0 * T0 * VdseffCV * T7); Csg = CoxWL * (T4 + T5 * dVdseffCV_dVg); Csd = CoxWL * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd; Csb = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Csg * dVgsteff_dVb; Csg *= dVgsteff_dVg; }else if (m->xpart < 0.5) { trace0("40/60 Charge petition model"); T1 = T1 / 12.0; double T2 = 0.5 * CoxWL / (T1 * T1); double T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff * (Vgsteff - 4.0 * T0 / 3.0)) - 2.0 * T0 * T0 * T0 / 15.0; qsrc = -T2 * T3; double T7 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0) + 0.4 * T0 * T0; double T4 = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0 * Vgsteff - 8.0 * T0 / 3.0) + 2.0 * T0 * T0 / 3.0); double T5 = (qsrc / T1 + T2 * T7) * AbulkCV; double T6 = (qsrc / T1 * VdseffCV + T2 * T7 * VdseffCV); Csg = (T4 + T5 * dVdseffCV_dVg); Csd = T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd; Csb = (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Csg * dVgsteff_dVb; Csg *= dVgsteff_dVg; }else{ trace0("50/50 Charge petition model"); qsrc = -0.5 * (d->qgate + d->qbulk); Csg = -0.5 * (Cgg1 + Cbg1); Csb = -0.5 * (Cgb1 + Cbb1); Csd = -0.5 * (Cgd1 + Cbd1); } trace4("", Csg, Csd, Csb, qsrc); d->qgate += Qac0 + Qsub0; d->qbulk -= (Qac0 + Qsub0); d->qdrn = -(d->qgate + d->qbulk + qsrc); trace3("2-2", d->qgate, d->qbulk, d->qdrn); double Cgg = dQac0_dVg + dQsub0_dVg + Cgg1; //double Cgd = dQac0_dVd + dQsub0_dVd + Cgd1; double Cgd = dQsub0_dVd + Cgd1; double Cgb = dQac0_dVb + dQsub0_dVb + Cgb1; trace3("", Cgg, Cgd, Cgb); double Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg; //double Cbd = Cbd1 - dQac0_dVd - dQsub0_dVd; double Cbd = Cbd1 - dQsub0_dVd; double Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb; trace3("", Cbg, Cbd, Cbb); Cgb *= dVbseff_dVb; Cbb *= dVbseff_dVb; Csb *= dVbseff_dVb; trace3("adjusted", Cgb, Cbb, Csb); d->cggb = Cgg; d->cgsb = -(Cgg + Cgd + Cgb); d->cgdb = Cgd; d->cdgb = -(Cgg + Cbg + Csg); d->cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb); d->cddb = -(Cgd + Cbd + Csd); d->cbgb = Cbg; d->cbsb = -(Cbg + Cbd + Cbb); d->cbdb = Cbd; trace0("end capMod == 2"); assert(d->qbulk == d->qbulk); assert(d->qdrn == d->qdrn); assert(d->qgate == d->qgate); }else if (m->capMod == 3) { trace0("begin capMod == 3"); double Vfbeff, dVfbeff_dVg, dVfbeff_dVb; { const double DELTA_3 = 0.02; double V3 = t->vfbzb - Vgs_eff + VbseffCV - DELTA_3; double T0; if (t->vfbzb <= 0.0) { T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * t->vfbzb); //T2 = -DELTA_3 / T0; }else{ T0 = sqrt(V3 * V3 + 4.0 * DELTA_3 * t->vfbzb); //T2 = DELTA_3 / T0; } double T1 = 0.5 * (1.0 + V3 / T0); Vfbeff = t->vfbzb - 0.5 * (V3 + T0); dVfbeff_dVg = T1 * dVgs_eff_dVg; dVfbeff_dVb = -T1 * dVbseffCV_dVb; } double Cox = m->cox; double Tox = 1.0e8 * m->tox; trace2("", Cox, Tox); double Qac0, dQac0_dVg, dQac0_dVb; double Qsub0, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb; { double Coxeff, dCoxeff_dVg, dCoxeff_dVb, CoxWLcen; { double Tcen, dTcen_dVg, dTcen_dVb; { double T0 = (Vgs_eff - VbseffCV - t->vfbzb) / Tox; double tmp = T0 * s->acde; trace2("", T0, tmp); if ((-EXP_THRESHOLD < tmp) && (tmp < EXP_THRESHOLD)) { double dT0_dVg = dVgs_eff_dVg / Tox; double dT0_dVb = -dVbseffCV_dVb / Tox; trace4("", dT0_dVg, dT0_dVb, s->ldeb, exp(tmp)); Tcen = s->ldeb * exp(tmp); dTcen_dVg = s->acde * Tcen; dTcen_dVb = dTcen_dVg * dT0_dVb; dTcen_dVg *= dT0_dVg; }else if (tmp <= -EXP_THRESHOLD) { Tcen = s->ldeb * MIN_EXP; dTcen_dVg = dTcen_dVb = 0.0; }else{ Tcen = s->ldeb * MAX_EXP; dTcen_dVg = dTcen_dVb = 0.0; } trace3("1", Tcen, dTcen_dVg, dTcen_dVb); double LINK = 1.0e-3 * m->tox; double V3 = s->ldeb - Tcen - LINK; double V4 = sqrt(V3 * V3 + 4.0 * LINK * s->ldeb); double T1 = 0.5 * (1.0 + V3 / V4); trace4("", LINK, V3, V4, T1); Tcen = s->ldeb - 0.5 * (V3 + V4); dTcen_dVg *= T1; dTcen_dVb *= T1; } trace3("2", Tcen, dTcen_dVg, dTcen_dVb); { double Ccen = P_EPS_SI / Tcen; double T2 = Cox / (Cox + Ccen); double T3 = -Ccen / Tcen; trace3("Coxeff", Ccen, T2, T3); Coxeff = T2 * Ccen; dCoxeff_dVg = T2 * T2 * T3; dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb; dCoxeff_dVg *= dTcen_dVg; CoxWLcen = CoxWL * Coxeff / Cox; } } trace4("", Coxeff, dCoxeff_dVg, dCoxeff_dVb, CoxWLcen); //double Qac0, dQac0_dVg, dQac0_dVb; { trace4("Qac0", CoxWLcen, Vfbeff, t->vfbzb, Coxeff); Qac0 = CoxWLcen * (Vfbeff - t->vfbzb); double QovCox = Qac0 / Coxeff; dQac0_dVg = CoxWLcen * dVfbeff_dVg + QovCox * dCoxeff_dVg; dQac0_dVb = CoxWLcen * dVfbeff_dVb + QovCox * dCoxeff_dVb; } trace3("", Qac0, dQac0_dVg, dQac0_dVb); //double Qsub0, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb; { double T0 = 0.5 * t->k1ox; double T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff; double T1, T2; if (t->k1ox == 0.0) { T1 = 0.0; T2 = 0.0; }else if (T3 < 0.0) { T1 = T0 + T3 / t->k1ox; T2 = CoxWLcen; }else{ T1 = sqrt(T0 * T0 + T3); T2 = CoxWLcen * T0 / T1; } Qsub0 = CoxWLcen * t->k1ox * (T1 - T0); double QovCox = Qsub0 / Coxeff; dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg) + QovCox * dCoxeff_dVg; dQsub0_dVd = -T2 * dVgsteff_dVd; dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb + dVgsteff_dVb) + QovCox * dCoxeff_dVb; } trace4("", Qsub0, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb); } // end scope Coxeff, CoxWLcen assert(Qac0 == Qac0); assert(Qsub0 == Qsub0); double VgDP, dVgDP_dVg; { double DeltaPhi, dDeltaPhi_dVg; { /* Gate-bias dependent delta Phis begins */ double Denomi, T0; if (t->k1ox <= 0.0) { Denomi = 0.25 * s->moin * t->vtm; T0 = 0.5 * t->sqrtPhi; }else{ Denomi = s->moin * t->vtm * t->k1ox * t->k1ox; T0 = t->k1ox * t->sqrtPhi; } double T1 = 2.0 * T0 + Vgsteff; DeltaPhi = t->vtm * log(1.0 + T1 * Vgsteff / Denomi); dDeltaPhi_dVg = 2.0 * t->vtm * (T1-T0) / (Denomi + T1 * Vgsteff); } /* VgDP = Vgsteff - DeltaPhi */ double T0 = Vgsteff - DeltaPhi - 0.001; double dT0_dVg = 1.0 - dDeltaPhi_dVg; double T1 = sqrt(T0 * T0 + Vgsteff * 0.004); VgDP = 0.5 * (T0 + T1); dVgDP_dVg = 0.5 * (dT0_dVg + (T0 * dT0_dVg + 0.002) / T1); } double Coxeff, dCoxeff_dVg, dCoxeff_dVd, dCoxeff_dVb; { double Tcen, dTcen_dVg, dTcen_dVd, dTcen_dVb; { double T3 = 4.0 * (d->von - t->vfbzb - t->phi); Tox += Tox; double T0, dT0_dVd, dT0_dVb; if (T3 >= 0.0) { T0 = (Vgsteff + T3) / Tox; dT0_dVd = (dVgsteff_dVd + 4.0 * dVth_dVd) / Tox; dT0_dVb = (dVgsteff_dVb + 4.0 * dVth_dVb) / Tox; }else{ T0 = (Vgsteff + 1.0e-20) / Tox; dT0_dVd = dVgsteff_dVd / Tox; dT0_dVb = dVgsteff_dVb / Tox; } double tmp = exp(0.7 * log(T0)); double T1 = 1.0 + tmp; double T2 = 0.7 * tmp / (T0 * Tox); Tcen = 1.9e-9 / T1; dTcen_dVg = -1.9e-9 * T2 / T1 /T1; dTcen_dVd = Tox * dTcen_dVg; dTcen_dVb = dTcen_dVd * dT0_dVb; dTcen_dVd *= dT0_dVd; dTcen_dVg *= dVgsteff_dVg; } double Ccen = P_EPS_SI / Tcen; double T0 = Cox / (Cox + Ccen); Coxeff = T0 * Ccen; double T1 = -Ccen / Tcen; dCoxeff_dVg = T0 * T0 * T1; dCoxeff_dVd = dCoxeff_dVg * dTcen_dVd; dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb; dCoxeff_dVg *= dTcen_dVg; } double CoxWLcen = CoxWL * Coxeff / Cox; double AbulkCV = Abulk0 * s->abulkCVfactor; double dAbulkCV_dVb = s->abulkCVfactor * dAbulk0_dVb; double VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb; { const double DELTA_4 = 0.02; double VdsatCV = VgDP / AbulkCV; double T0 = VdsatCV - d->vds - DELTA_4; double dT0_dVg = dVgDP_dVg / AbulkCV; double dT0_dVb = -VdsatCV * dAbulkCV_dVb / AbulkCV; double T1 = sqrt(T0 * T0 + 4.0 * DELTA_4 * VdsatCV); double dT1_dVg = (T0 + DELTA_4 + DELTA_4) / T1; double dT1_dVd = -T0 / T1; double dT1_dVb = dT1_dVg * dT0_dVb; dT1_dVg *= dT0_dVg; if (T0 >= 0.0) { VdseffCV = VdsatCV - 0.5 * (T0 + T1); dVdseffCV_dVg = 0.5 * (dT0_dVg - dT1_dVg); dVdseffCV_dVd = 0.5 * (1.0 - dT1_dVd); dVdseffCV_dVb = 0.5 * (dT0_dVb - dT1_dVb); }else{ double T3 = (DELTA_4 + DELTA_4) / (T1 - T0); double T4 = 1.0 - T3; double T5 = VdsatCV * T3 / (T1 - T0); VdseffCV = VdsatCV * T4; dVdseffCV_dVg = dT0_dVg * T4 + T5 * (dT1_dVg - dT0_dVg); dVdseffCV_dVd = T5 * (dT1_dVd + 1.0); dVdseffCV_dVb = dT0_dVb * (1.0 - T5) + T5 * dT1_dVb; } /* Added to eliminate non-zero VdseffCV at Vds=0.0 */ if (d->vds == 0.0) { VdseffCV = 0.0; dVdseffCV_dVg = 0.0; dVdseffCV_dVb = 0.0; } } double T0 = AbulkCV * VdseffCV; double T1 = VgDP; double T2 = 12.0 * (T1 - 0.5 * T0 + 1.0e-20); double T3 = T0 / T2; double T4 = 1.0 - 12.0 * T3 * T3; double T5 = AbulkCV * (6.0 * T0 * (4.0 * T1 - T0) / (T2*T2) - 0.5); double T6 = T5 * VdseffCV / AbulkCV; d->qgate = CoxWLcen * (T1 - T0 * (0.5 - T3)); //////////double qinoi = qgate; double Cgg1, Cgd1, Cgb1; { double QovCox = d->qgate / Coxeff; Cgg1 = CoxWLcen * (T4 * dVgDP_dVg + T5 * dVdseffCV_dVg); Cgd1 = CoxWLcen * T5 * dVdseffCV_dVd + Cgg1 * dVgsteff_dVd + QovCox * dCoxeff_dVd; Cgb1 = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Cgg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb; Cgg1 = Cgg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg; } double T7 = 1.0 - AbulkCV; double T8 = T2 * T2; double T9 = 12.0 * T7 * T0 * T0 / (T8 * AbulkCV); double T10 = T9 * dVgDP_dVg; double T11 = -T7 * T5 / AbulkCV; double T12 = -(T9 * T1 / AbulkCV + VdseffCV * (0.5 - T0 / T2)); d->qbulk = CoxWLcen * T7 * (0.5 * VdseffCV - T0 * VdseffCV / T2); assert(d->qbulk == d->qbulk); assert(d->qdrn == d->qdrn); assert(d->qgate == d->qgate); double Cbg1, Cbd1, Cbb1; { double QovCox = d->qbulk / Coxeff; Cbg1 = CoxWLcen * (T10 + T11 * dVdseffCV_dVg); Cbd1 = CoxWLcen * T11 * dVdseffCV_dVd + Cbg1 * dVgsteff_dVd + QovCox * dCoxeff_dVd; Cbb1 = CoxWLcen * (T11 * dVdseffCV_dVb + T12 * dAbulkCV_dVb) + Cbg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb; Cbg1 = Cbg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg; } //////////qsrc -- scope too wide?? double Csg, Csd, Csb; if (m->xpart > 0.5) { /* 0/100 partition */ qsrc = -CoxWLcen * (T1 / 2.0 + T0 / 4.0 - 0.5 * T0 * T0 / T2); double QovCox = qsrc / Coxeff; T2 += T2; T3 = T2 * T2; T7 = -(0.25 - 12.0 * T0 * (4.0 * T1 - T0) / T3); T4 = -(0.5 + 24.0 * T0 * T0 / T3) * dVgDP_dVg; T5 = T7 * AbulkCV; T6 = T7 * VdseffCV; Csg = CoxWLcen * (T4 + T5 * dVdseffCV_dVg); Csd = CoxWLcen * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd + QovCox * dCoxeff_dVd; Csb = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Csg * dVgsteff_dVb + QovCox * dCoxeff_dVb; Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg; }else if (m->xpart < 0.5) { /* 40/60 partition */ T2 = T2 / 12.0; T3 = 0.5 * CoxWLcen / (T2 * T2); T4 = T1 * (2.0 * T0 * T0 / 3.0 + T1 * (T1 - 4.0 * T0 / 3.0)) - 2.0 * T0 * T0 * T0 / 15.0; qsrc = -T3 * T4; double QovCox = qsrc / Coxeff; T8 = 4.0 / 3.0 * T1 * (T1 - T0) + 0.4 * T0 * T0; T5 = -2.0 * qsrc / T2 - T3 * (T1 * (3.0 * T1 - 8.0 * T0 / 3.0) + 2.0 * T0 * T0 / 3.0); T6 = AbulkCV * (qsrc / T2 + T3 * T8); T7 = T6 * VdseffCV / AbulkCV; Csg = T5 * dVgDP_dVg + T6 * dVdseffCV_dVg; Csd = Csg * dVgsteff_dVd + T6 * dVdseffCV_dVd + QovCox * dCoxeff_dVd; Csb = Csg * dVgsteff_dVb + T6 * dVdseffCV_dVb + T7 * dAbulkCV_dVb + QovCox * dCoxeff_dVb; Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg; }else{ /* 50/50 partition */ qsrc = -0.5 * d->qgate; Csg = -0.5 * Cgg1; Csd = -0.5 * Cgd1; Csb = -0.5 * Cgb1; } ////////// assert(Qsub0 == Qsub0); assert(Qac0 == Qac0); d->qgate += Qac0 + Qsub0 - d->qbulk; d->qbulk -= (Qac0 + Qsub0); d->qdrn = -(d->qgate + d->qbulk + qsrc); assert(d->qbulk == d->qbulk); assert(d->qdrn == d->qdrn); assert(d->qgate == d->qgate); { double Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg; double Cbd = Cbd1 - dQsub0_dVd; double Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb; double Cgg = Cgg1 - Cbg; double Cgd = Cgd1 - Cbd; double Cgb = Cgb1 - Cbb; Cgb *= dVbseff_dVb; Cbb *= dVbseff_dVb; Csb *= dVbseff_dVb; d->cggb = Cgg; d->cgsb = -(Cgg + Cgd + Cgb); d->cgdb = Cgd; d->cdgb = -(Cgg + Cbg + Csg); d->cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb); d->cddb = -(Cgd + Cbd + Csd); d->cbgb = Cbg; d->cbsb = -(Cbg + Cbd + Cbb); d->cbdb = Cbd; } ////////// d->qinv = -qinoi; assert(d->qbulk == d->qbulk); assert(d->qdrn == d->qdrn); assert(d->qgate == d->qgate); }else{ error(bDANGER, "illegal capmod = %d\n", int(m->capMod)); d->qgate = d->qdrn = d->qbulk = 0.0; d->cggb = d->cgsb = d->cgdb = 0.0; d->cdgb = d->cdsb = d->cddb = 0.0; d->cbgb = d->cbsb = d->cbdb = 0.0; ////////// d->cqdb = d->cqsb = d->cqgb = d->cqbb = 0.0; ////////// d->gtau = 0.0; trace0("xpart < 0 || no charge computation"); untested(); assert(d->qbulk == d->qbulk); assert(d->qdrn == d->qdrn); assert(d->qgate == d->qgate); untested(); } assert(d->qbulk == d->qbulk); assert(d->qdrn == d->qdrn); assert(d->qgate == d->qgate); /* Non-quasi-static Model */ double tconst; if (m->nqsMod) { // d->gtau double qcheq = -d->qbulk - d->qgate; double T0 = s->leffCV * s->leffCV; tconst = t->u0temp * s->elm / CoxWL / T0; if (qcheq == 0.0) { tconst = 0.0; }else if (qcheq < 0.0) { tconst = -tconst; }else{ } double gtau_drift = std::abs(tconst * qcheq); double gtau_diff = 16.0 * t->u0temp * t->vtm / T0; d->gtau = gtau_drift + gtau_diff; d->cqgb = -(d->cggb + d->cbgb); d->cqdb = -(d->cgdb + d->cbdb); d->cqsb = -(d->cgsb + d->cbsb); d->cqbb = d->cggb +d->cgdb +d->cgsb +d->cbgb +d->cbdb +d->cbsb; d->qbulk = d->qgate = d->qdrn = qsrc = 0.0; d->cggb = d->cgsb = d->cgdb = 0.0; d->cdgb = d->cdsb = d->cddb = 0.0; d->cbgb = d->cbsb = d->cbdb = 0.0; #if 0 *(ckt->CKTstate0 + d->qcheq) = qcheq; if (ckt->CKTmode & MODEINITTRAN) *(ckt->CKTstate1 + d->qcheq) = *(ckt->CKTstate0 + d->qcheq); error = NIintegrate(ckt, &geq, &ceq, 0.0, d->qcheq); if (error) return (error); #endif }else{ d->gtau = 0.0; d->cqgb = d->cqdb = d->cqsb = d->cqbb = 0.0; } } } if (d->reversed) { d->qdrn = -d->qdrn; d->cdgb = -d->cdgb; { double t1 = d->cdsb; d->cdsb = -d->cddb; d->cddb = -t1; } d->qgd = d->qgate; d->cgdgb = d->cggb; d->cgdsb = d->cgsb; d->cgddb = d->cgdb; d->qgs = 0.; d->cgsgb = 0.; d->cgssb = 0.; d->cgsdb = 0.; d->qbd = d->qbulk; d->cbdgb = d->cbgb; d->cbdsb = d->cbsb; d->cbddb = d->cbdb; d->qbs = 0.; d->cbsgb = 0.; d->cbssb = 0.; d->cbsdb = 0.; }else{ d->qgs = d->qgate; d->cgsgb = d->cggb; d->cgssb = d->cgsb; d->cgsdb = d->cgdb; d->qgd = 0.; d->cgdgb = 0.; d->cgdsb = 0.; d->cgddb = 0.; d->qbs = d->qbulk; d->cbsgb = d->cbgb; d->cbssb = d->cbsb; d->cbsdb = d->cbdb; d->qbd = 0.; d->cbdgb = 0.; d->cbdsb = 0.; d->cbddb = 0.; } assert(d->qbulk == d->qbulk); assert(d->qdrn == d->qdrn); assert(d->qgate == d->qgate); trace0("mos8"); trace4("", d->qgate, d->cggb, d->cgsb, d->cgdb); trace4("", d->qdrn, d->cdgb, d->cdsb, d->cddb); trace4("", d->qbulk, d->cbgb, d->cbsb, d->cbdb); trace2("", d->ids, d->gds); trace4("", d->gmf, d->gmr, d->gmbf, d->gmbr); trace4("", d->isub, d->gbbs, d->gbgs, d->gbds); trace4("", d->qgate, d->cggb, d->cgsb, d->cgdb); trace4("", d->qdrn, d->cdgb, d->cdsb, d->cddb); trace4("", d->qbulk, d->cbgb, d->cbsb, d->cbdb); trace1("", d->gtau); trace4("", d->cqgb, d->cqsb, d->cqdb, d->cqbb); //trace1("", d->tconst); //trace2("", d->cgb, d->qgb); //trace2("", d->qgd, d->cgd); trace2("", d->qgs, d->cgs); trace3("", d->vgs, d->vds, d->vbs); trace3("", d->vdsat, d->vgst, d->von); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_mos_base.model��������������������������������������������������������������������������������0000664�0000000�0000000�00000017102�11454012162�0014757�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: d_mos_base.model,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * MOS model - base for levels 1,2,3,6 */ h_headers { #include "d_mos.h" } cc_headers { const double mDEFAULT_is = 1e-14; } /*--------------------------------------------------------------------------*/ model BUILT_IN_MOS_BASE { dev_type BUILT_IN_MOS; hide_base; inherit BUILT_IN_DIODE; private_keys { nmos polarity=pN; pmos polarity=pP; } validate { c->l_in.e_val(OPT::defl,d->scope()); c->w_in.e_val(OPT::defw,d->scope()); m->lmin.e_val(0,m->scope()); m->lmax.e_val(INF,m->scope()); m->wmin.e_val(0,m->scope()); m->wmax.e_val(INF,m->scope()); return c->l_in >= m->lmin && c->l_in <= m->lmax && c->w_in >= m->wmin && c->w_in <= m->wmax; } independent { override { double _tnom_c "" name=TNOM default=OPT::tnom_c; double fc "coef for fwd bias depl cap formula" name=FC; double pb "junction potential" name=PB positive; double cjo "zero-bias jct capacitance (per area)" name=CJ; double mj "grading coefficient" name=MJ; double cjsw "zero bias sidewall cap (per perim.)" name=CJSW; double pbsw "sidewall junction potential" name=PBSW print_test="pbsw != pb"; double mjsw "sidewall grading coefficient" name=MJSW; double kf "flicker noise coefficient" name=KF print_test="has_good_value(kf)"; double af "flicker noise exponent" name=AF print_test="has_good_value(af)"; } raw_parameters { int level "dummy" name=LEVEL default=1 print_test=false; double wmax "max width" name=WMAX positive default=INF print_test="wmaxis_first_expand()) ? (bDEBUG) : (bWARNING)), long_label() + ": rd input, but not rs. setting rs = 0.\n"); rs.set_default(0.); }else if ((!has_hard_value(rd)) && has_hard_value(rs)) {untested();//109 error(((!_sim->is_first_expand()) ? (bDEBUG) : (bWARNING)), long_label() + ": rs input, but not rd. setting rd = 0.\n"); rd.set_default(0.); }else{ /* rd, rs are ok, either have both or neither */ } if (has_hard_value(rsh) && (has_hard_value(rd) || has_hard_value(rs))) { error(((!_sim->is_first_expand()) ? (bDEBUG) : (bWARNING)), long_label() + ": rsh - rs - rd conflict: using " + (((rd <= 0.) && (rs <= 0.)) ? "rsh" : "rs,rd") + '\n'); }else if (!has_hard_value(rsh) && (!has_hard_value(rd)) && (!has_hard_value(rs))) { // don't have anything }else{ /* rsh, rd are ok, have one or other */ } if (!has_hard_value(is) && !has_hard_value(js)) { /* don't have either, use default is */ }else if (has_hard_value(is) && has_hard_value(js)) { error(((!_sim->is_first_expand()) ? (bDEBUG) : (bWARNING)), long_label() + ": is - js conflict\n"); }else{ /* is, js are ok, have one or other */ } } } size_dependent { calculated_parameters { double l_eff "-23-c- actual (electrical) channel length" calculate="(has_hard_value(c->l_in)) ? c->l_in * m->lmlt + m->xl - 2. * (m->ld + m->del) : OPT::defl"; double w_eff "--3-c- actual (electrical) channel width" calculate="(has_hard_value(c->w_in)) ? c->w_in * m->wmlt + m->xw - 2. * m->wd : OPT::defw"; double ad "----c- drain area, actual" calculate="(has_hard_value(c->ad_in)) ? c->ad_in : OPT::defad"; double as "----c- source area, actual" calculate="(has_hard_value(c->as_in)) ? c->as_in : OPT::defas"; double cgate "-----b gate to channel capacitance" calculate=NA; double idsat "-----b drain junction saturation current"; double issat "-----b source junction saturation current"; double rd "-----b ohmic drain resistance"; double rs "-----b ohmic source resistance"; double phi "surface potential at strong inversion" calculate=NA; double cgso "" calculate="m->cgso * w_eff"; double cgdo "" calculate="m->cgdo * w_eff"; double cgbo "" calculate="m->cgbo * l_eff"; } code_post { if (has_hard_value(m->rd) || has_hard_value(m->rs)) { rd = m->rd; rs = m->rs; }else{ rd = m->rsh * c->nrd; rs = m->rsh * c->nrs; } if (!has_hard_value(m->js) || ad == 0. || as == 0.) { idsat = issat = m->is; /* this convoluted logic */ }else{ /* is for Spice compatibility */ idsat = m->js * ad; issat = m->js * as; } } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_poly_cap.cc�����������������������������������������������������������������������������������0000664�0000000�0000000�00000023131�11454012162�0014261�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_poly_cap.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * DEV_CPOLY_CAP * number of nodes = 2*n_ports * number of val, ov = n_ports+1 * val[0] is the constant part, val[1] is self admittance, * val[2+] are transadmittances, up to n_ports * node[0] and node[1] are the output. * node[2] up are inputs. * node[2*i] and node[2*i+1] correspond to val[i+1] */ //testing=script 2006.07.17 #include "e_storag.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class DEV_CPOLY_CAP : public STORAGE { protected: double* _vy0; // vector form of _y0 _values; charge, capacitance double* _vy1; // vector form of _y1 _old_values; double* _vi0; // vector form of _i0; current, difference conductance double* _vi1; // vector form of _i1 int _n_ports; double _load_time; const double** _inputs; protected: explicit DEV_CPOLY_CAP(const DEV_CPOLY_CAP& p); public: explicit DEV_CPOLY_CAP(); ~DEV_CPOLY_CAP(); protected: // override virtual char id_letter()const {unreachable(); return '\0';} std::string value_name()const {incomplete(); return "";} std::string dev_type()const {unreachable(); return "cpoly_cap";} int max_nodes()const {return net_nodes();} int min_nodes()const {return net_nodes();} int matrix_nodes()const {return _n_ports*2;} int net_nodes()const {return _n_ports*2;} CARD* clone()const {unreachable();return new DEV_CPOLY_CAP(*this);} void tr_iwant_matrix() {tr_iwant_matrix_extended();} bool tr_needs_eval()const {/*assert(!is_q_for_eval());*/ return true;} bool do_tr(); void tr_load(); TIME_PAIR tr_review() {return _time_by.reset();}//BUG//review(_i0.f0, _it1.f0);} void tr_unload(); double tr_involts()const {unreachable(); return NOT_VALID;} double tr_involts_limited()const {unreachable(); return NOT_VALID;} double tr_amps()const; void ac_iwant_matrix() {ac_iwant_matrix_extended();} void ac_load(); COMPLEX ac_involts()const {itested(); return NOT_VALID;} COMPLEX ac_amps()const {itested(); return NOT_VALID;} std::string port_name(int)const {untested(); incomplete(); unreachable(); return ""; } public: void set_parameters(const std::string& Label, CARD* Parent, COMMON_COMPONENT* Common, double Value, int state_count, double state[], int node_count, const node_t nodes[]); // const double* inputs[]=0); protected: bool do_tr_con_chk_and_q(); }; /*--------------------------------------------------------------------------*/ class DEV_FPOLY_CAP : public DEV_CPOLY_CAP { private: explicit DEV_FPOLY_CAP(const DEV_FPOLY_CAP& p) :DEV_CPOLY_CAP(p) {} public: explicit DEV_FPOLY_CAP() :DEV_CPOLY_CAP() {} private: // override virtual char id_letter()const {unreachable(); return '\0';} std::string dev_type()const{unreachable(); return "fpoly_cap";} CARD* clone()const {return new DEV_FPOLY_CAP(*this);} bool do_tr(); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_CPOLY_CAP::DEV_CPOLY_CAP(const DEV_CPOLY_CAP& p) :STORAGE(p), _vy0(NULL), _vy1(NULL), _vi0(NULL), _vi1(NULL), _n_ports(p._n_ports), _load_time(NOT_VALID), _inputs(NULL) { // not really a copy .. only valid to copy a default // too lazy to do it right, and that's all that is being used // to do it correctly requires a deep copy // just filling in defaults is better than a shallow copy, hence this: assert(!p._vy0); assert(!p._vy1); assert(!p._vi0); assert(!p._vi1); assert(p._n_ports == 0); assert(!p._inputs); } /*--------------------------------------------------------------------------*/ DEV_CPOLY_CAP::DEV_CPOLY_CAP() :STORAGE(), _vy0(NULL), _vy1(NULL), _vi0(NULL), _vi1(NULL), _n_ports(0), _load_time(NOT_VALID), _inputs(NULL) { } /*--------------------------------------------------------------------------*/ DEV_CPOLY_CAP::~DEV_CPOLY_CAP() { delete [] _vy1; delete [] _vi0; delete [] _vi1; if (net_nodes() > NODES_PER_BRANCH) {untested(); delete [] _n; }else{ // it is part of a base class } } /*--------------------------------------------------------------------------*/ bool DEV_CPOLY_CAP::do_tr_con_chk_and_q() { q_load(); assert(_vy1); set_converged(conchk(_load_time, _sim->_time0)); _load_time = _sim->_time0; for (int i=0; converged() && i<=_n_ports; ++i) { set_converged(conchk(_vy1[i], _vy0[i])); } set_converged(); return converged(); } /*--------------------------------------------------------------------------*/ bool DEV_CPOLY_CAP::do_tr() {untested(); incomplete(); _m0 = CPOLY1(0., _vi0[0], _vi0[1]); return do_tr_con_chk_and_q(); } /*--------------------------------------------------------------------------*/ bool DEV_FPOLY_CAP::do_tr() { assert((_time[0] == 0) || (_vy0[0] == _vy0[0])); _y[0].x = tr_outvolts(); _y[0].f0 = _vy0[0]; _y[0].f1 = _vy0[1]; _i[0] = differentiate(_y, _i, _time, _method_a); _vi0[0] = _i[0].f0; _vi0[1] = _i[0].f1; assert(_vi0[0] == _vi0[0]); if (_inputs) {untested(); for (int i=1; i<=_n_ports; ++i) {untested(); _vi0[i] = tr_c_to_g(_vy0[i], _vi0[i]); _vi0[0] -= *(_inputs[i]) * _vi0[i]; } }else{ for (int i=1; i<=_n_ports; ++i) { _vi0[i] = tr_c_to_g(_vy0[i], _vi0[i]); _vi0[0] -= volts_limited(_n[2*i-2],_n[2*i-1]) * _vi0[i]; assert(_vi0[i] == _vi0[i]); assert(_vi0[0] == _vi0[0]); } } for (int i=0; i<=_n_ports; ++i) { assert(_vi0[i] == _vi0[i]); } _m0 = CPOLY1(0., _vi0[0], _vi0[1]); return do_tr_con_chk_and_q(); } /*--------------------------------------------------------------------------*/ void DEV_CPOLY_CAP::tr_load() { for (int i=0; i<=_n_ports; ++i) { assert(_vi0[i] == _vi0[i]); } tr_load_passive(); _vi1[0] = _vi0[0]; _vi1[1] = _vi0[1]; for (int i=2; i<=_n_ports; ++i) { tr_load_extended(_n[OUT1], _n[OUT2], _n[2*i-2], _n[2*i-1], &(_vi0[i]), &(_vi1[i])); } } /*--------------------------------------------------------------------------*/ void DEV_CPOLY_CAP::tr_unload() {untested(); std::fill_n(_vi0, _n_ports+1, 0.); _m0.c0 = _m0.c1 = 0.; _sim->mark_inc_mode_bad(); tr_load(); } /*--------------------------------------------------------------------------*/ double DEV_CPOLY_CAP::tr_amps()const {untested(); double amps = _m0.c0; for (int i=1; i<=_n_ports; ++i) {untested(); amps += dn_diff(_n[2*i-2].v0(),_n[2*i-1].v0()) * _vi0[i]; } return amps; } /*--------------------------------------------------------------------------*/ void DEV_CPOLY_CAP::ac_load() { _acg = _vy0[1] * _sim->_jomega; ac_load_passive(); for (int i=2; i<=_n_ports; ++i) { ac_load_extended(_n[OUT1], _n[OUT2], _n[2*i-2], _n[2*i-1], _vy0[i] * _sim->_jomega); } } /*--------------------------------------------------------------------------*/ /* set: set parameters, used in model building */ void DEV_CPOLY_CAP::set_parameters(const std::string& Label, CARD *Owner, COMMON_COMPONENT *Common, double Value, int n_states, double states[], int n_nodes, const node_t nodes[]) // const double* inputs[]) { bool first_time = (net_nodes() == 0); set_label(Label); set_owner(Owner); set_value(Value); attach_common(Common); if (first_time) { _n_ports = n_nodes/2; // sets num_nodes() = _n_ports*2 assert(_n_ports == n_states-1); assert(!_vy1); assert(!_vi0); assert(!_vi1); _vy1 = new double[n_states]; _vi0 = new double[n_states]; _vi1 = new double[n_states]; if (net_nodes() > NODES_PER_BRANCH) {untested(); // allocate a bigger node list _n = new node_t[net_nodes()]; }else{ // use the default node list, already set } }else{itested(); assert(_n_ports == n_states-1); assert(_vy1); assert(_vi0); assert(_vi1); assert(net_nodes() == n_nodes); // assert could fail if changing the number of nodes after a run } //_inputs = inputs; _inputs = 0; _vy0 = states; std::fill_n(_vy0, n_states, 0.); std::fill_n(_vy1, n_states, 0.); std::fill_n(_vi0, n_states, 0.); std::fill_n(_vi1, n_states, 0.); notstd::copy_n(nodes, net_nodes(), _n); assert(net_nodes() == _n_ports * 2); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_FPOLY_CAP p4; DISPATCHER::INSTALL d4(&device_dispatcher, "fpoly_cap", &p4); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_poly_g.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000021215�11454012162�0013745�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_poly_g.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * DEV_CPOLY_G * number of nodes = 2*n_ports * number of val, ov = n_ports+1 * val[0] is the constant part, val[1] is self admittance, * val[2+] are transadmittances, up to n_ports * node[0] and node[1] are the output. * node[2] up are inputs. * node[2*i] and node[2*i+1] correspond to val[i+1] */ //testing=script 2006.07.17 #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class DEV_CPOLY_G : public ELEMENT { protected: double* _values; double* _old_values; int _n_ports; double _time; const double** _inputs; protected: explicit DEV_CPOLY_G(const DEV_CPOLY_G& p); public: explicit DEV_CPOLY_G(); ~DEV_CPOLY_G(); protected: // override virtual char id_letter()const {unreachable(); return '\0';} std::string value_name()const {incomplete(); return "";} std::string dev_type()const {unreachable(); return "cpoly_g";} int max_nodes()const {return net_nodes();} int min_nodes()const {return net_nodes();} int matrix_nodes()const {return _n_ports*2;} int net_nodes()const {return _n_ports*2;} CARD* clone()const {return new DEV_CPOLY_G(*this);} void tr_iwant_matrix() {tr_iwant_matrix_extended();} bool do_tr(); void tr_load(); void tr_unload(); double tr_involts()const {unreachable(); return NOT_VALID;} double tr_involts_limited()const {unreachable(); return NOT_VALID;} double tr_amps()const; void ac_iwant_matrix() {ac_iwant_matrix_extended();} void ac_load(); COMPLEX ac_involts()const {itested(); return NOT_VALID;} COMPLEX ac_amps()const {itested(); return NOT_VALID;} std::string port_name(int)const {untested(); incomplete(); unreachable(); return ""; } public: void set_parameters(const std::string& Label, CARD* Parent, COMMON_COMPONENT* Common, double Value, int state_count, double state[], int node_count, const node_t nodes[]); // const double* inputs[]=0); protected: bool do_tr_con_chk_and_q(); }; /*--------------------------------------------------------------------------*/ #if 0 class DEV_FPOLY_G : public DEV_CPOLY_G { private: explicit DEV_FPOLY_G(const DEV_FPOLY_G& p) :DEV_CPOLY_G(p) {incomplete(); unreachable();} public: explicit DEV_FPOLY_G() :DEV_CPOLY_G() {untested();} private: // override virtual char id_letter()const {unreachable(); return '\0';} std::string dev_type()const {unreachable(); return "fpoly_g";} CARD* clone()const {unreachable(); return new DEV_FPOLY_G(*this);} bool do_tr(); }; #endif /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_CPOLY_G::DEV_CPOLY_G(const DEV_CPOLY_G& p) :ELEMENT(p), _values(NULL), _old_values(NULL), _n_ports(p._n_ports), _time(NOT_VALID), _inputs(NULL) { // not really a copy .. only valid to copy a default // too lazy to do it right, and that's all that is being used // to do it correctly requires a deep copy // just filling in defaults is better than a shallow copy, hence this: assert(!p._values); assert(!p._old_values); assert(p._n_ports == 0); assert(!p._inputs); } /*--------------------------------------------------------------------------*/ DEV_CPOLY_G::DEV_CPOLY_G() :ELEMENT(), _values(NULL), _old_values(NULL), _n_ports(0), _time(NOT_VALID), _inputs(NULL) { } /*--------------------------------------------------------------------------*/ DEV_CPOLY_G::~DEV_CPOLY_G() { delete [] _old_values; if (net_nodes() > NODES_PER_BRANCH) { delete [] _n; }else{ // it is part of a base class } } /*--------------------------------------------------------------------------*/ bool DEV_CPOLY_G::do_tr_con_chk_and_q() { q_load(); assert(_old_values); set_converged(conchk(_time, _sim->_time0)); _time = _sim->_time0; for (int i=0; converged() && i<=_n_ports; ++i) { set_converged(conchk(_old_values[i], _values[i])); } return converged(); } /*--------------------------------------------------------------------------*/ bool DEV_CPOLY_G::do_tr() { assert(_values); _m0 = CPOLY1(0., _values[0], _values[1]); return do_tr_con_chk_and_q(); } /*--------------------------------------------------------------------------*/ #if 0 bool DEV_FPOLY_G::do_tr() {untested(); assert(_values); double c0 = _values[0]; if (_inputs) {untested(); untested(); for (int i=1; i<=_n_ports; ++i) {untested(); c0 -= *(_inputs[i]) * _values[i]; trace4("", i, *(_inputs[i]), _values[i], *(_inputs[i]) * _values[i]); } }else{untested(); for (int i=1; i<=_n_ports; ++i) {untested(); c0 -= volts_limited(_n[2*i-2],_n[2*i-1]) * _values[i]; trace4("", i, volts_limited(_n[2*i-2],_n[2*i-1]), _values[i], volts_limited(_n[2*i-2],_n[2*i-1]) * _values[i]); } } trace2("", _values[0], c0); _m0 = CPOLY1(0., c0, _values[1]); return do_tr_con_chk_and_q(); } #endif /*--------------------------------------------------------------------------*/ void DEV_CPOLY_G::tr_load() { tr_load_passive(); _old_values[0] = _values[0]; _old_values[1] = _values[1]; for (int i=2; i<=_n_ports; ++i) { tr_load_extended(_n[OUT1], _n[OUT2], _n[2*i-2], _n[2*i-1], &(_values[i]), &(_old_values[i])); } } /*--------------------------------------------------------------------------*/ void DEV_CPOLY_G::tr_unload() { std::fill_n(_values, _n_ports+1, 0.); _m0.c0 = _m0.c1 = 0.; _sim->mark_inc_mode_bad(); tr_load(); } /*--------------------------------------------------------------------------*/ double DEV_CPOLY_G::tr_amps()const { double amps = _m0.c0; for (int i=1; i<=_n_ports; ++i) { amps += dn_diff(_n[2*i-2].v0(),_n[2*i-1].v0()) * _values[i]; } return amps; } /*--------------------------------------------------------------------------*/ void DEV_CPOLY_G::ac_load() { _acg = _values[1]; ac_load_passive(); for (int i=2; i<=_n_ports; ++i) { ac_load_extended(_n[OUT1], _n[OUT2], _n[2*i-2], _n[2*i-1], _values[i]); } } /*--------------------------------------------------------------------------*/ /* set: set parameters, used in model building */ void DEV_CPOLY_G::set_parameters(const std::string& Label, CARD *Owner, COMMON_COMPONENT *Common, double Value, int n_states, double states[], int n_nodes, const node_t nodes[]) // const double* inputs[]) { bool first_time = (net_nodes() == 0); set_label(Label); set_owner(Owner); set_value(Value); attach_common(Common); if (first_time) { _n_ports = n_nodes/2; // sets num_nodes() = _n_ports*2 assert(_n_ports == n_states-1); assert(!_old_values); _old_values = new double[n_states]; if (net_nodes() > NODES_PER_BRANCH) { // allocate a bigger node list _n = new node_t[net_nodes()]; }else{ // use the default node list, already set } }else{ assert(_n_ports == n_states-1); assert(_old_values); assert(net_nodes() == n_nodes); // assert could fail if changing the number of nodes after a run } //_inputs = inputs; _inputs = 0; _values = states; std::fill_n(_values, n_states, 0.); std::fill_n(_old_values, n_states, 0.); notstd::copy_n(nodes, net_nodes(), _n); assert(net_nodes() == _n_ports * 2); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_CPOLY_G p4; DISPATCHER::INSTALL d4(&device_dispatcher, "cpoly_g", &p4); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_res.cc����������������������������������������������������������������������������������������0000664�0000000�0000000�00000012026�11454012162�0013245�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_res.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * functions for resistor. * y.x = amps, y.f0 = volts, ev = y.f1 = ohms * m.x = volts, m.c0 = amps, acg = m.c1 = mhos. */ //testing=script,complete 2006.07.17 #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class DEV_RESISTANCE : public ELEMENT { private: explicit DEV_RESISTANCE(const DEV_RESISTANCE& p) :ELEMENT(p) {} public: explicit DEV_RESISTANCE() :ELEMENT() {} private: // override virtual char id_letter()const {return 'R';} std::string value_name()const {return "r";} std::string dev_type()const {return "resistor";} int max_nodes()const {return 2;} int min_nodes()const {return 2;} int matrix_nodes()const {return 2;} int net_nodes()const {return 2;} bool has_iv_probe()const {return true;} bool use_obsolete_callback_parse()const {return true;} CARD* clone()const {return new DEV_RESISTANCE(*this);} void precalc_last(); void tr_iwant_matrix() {tr_iwant_matrix_passive();} void tr_begin(); bool do_tr(); void tr_load() {tr_load_passive();} void tr_unload() {untested();tr_unload_passive();} double tr_involts()const {return tr_outvolts();} double tr_input()const {untested(); return _m0.c0 + _m0.c1 * tr_involts();} double tr_involts_limited()const {return tr_outvolts_limited();} double tr_input_limited()const {return _m0.c0+_m0.c1*tr_involts_limited();} void ac_iwant_matrix() {ac_iwant_matrix_passive();} void ac_begin() {_ev = _y[0].f1; _acg = 1. / _ev;} void do_ac(); void ac_load() {ac_load_passive();} COMPLEX ac_involts()const {return ac_outvolts();} std::string port_name(int i)const {itested(); assert(i >= 0); assert(i < 2); static std::string names[] = {"p", "n"}; return names[i]; } }; /*--------------------------------------------------------------------------*/ void DEV_RESISTANCE::precalc_last() { ELEMENT::precalc_last(); set_constant(!has_tr_eval()); set_converged(!has_tr_eval()); } /*--------------------------------------------------------------------------*/ void DEV_RESISTANCE::tr_begin() { ELEMENT::tr_begin(); _y1.f1 = _y[0].f1 = (value() != 0.) ? value() : OPT::shortckt; _m0.x = _y[0].x; _m0.c1 = 1./_y[0].f1; _m0.c0 = 0.; _m1 = _m0; assert(_loss0 == 0.); assert(_loss1 == 0.); if (value() == 0. && !has_common()) { error(bPICKY, long_label() + ": short circuit\n"); }else{ } } /*--------------------------------------------------------------------------*/ bool DEV_RESISTANCE::do_tr() { if (using_tr_eval()) { _m0.x = tr_involts_limited(); _y[0].x = tr_input_limited();; tr_eval(); assert(_y[0].f0 != LINEAR); if (_y[0].f1 == 0.) { error(bPICKY, long_label() + ": short circuit\n"); _y[0].f1 = OPT::shortckt; set_converged(conv_check()); }else{ } store_values(); q_load(); _m0.c1 = 1./_y[0].f1; _m0.c0 = _y[0].x - _y[0].f0 / _y[0].f1; }else{ assert(_y[0].f0 == LINEAR); assert(_y[0].f1 == value() || _y[0].f1 == OPT::shortckt); assert(conchk(_m0.c1, 1./_y[0].f1)); assert(_m0.c0 == 0.); assert(_y1 == _y[0]); assert(converged()); } return converged(); } /*--------------------------------------------------------------------------*/ void DEV_RESISTANCE::do_ac() { if (using_ac_eval()) { ac_eval(); if (_ev == 0.) { error(bPICKY, long_label() + ": short circuit\n"); _ev = OPT::shortckt; }else{ } _acg = 1. / _ev; }else{ assert(_ev == _y[0].f1); assert(has_tr_eval() || _ev == double(value()) || _ev == OPT::shortckt); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_RESISTANCE p1; DISPATCHER::INSTALL d1(&device_dispatcher, "R|resistor", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_subckt.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000020513�11454012162�0013747�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_subckt.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * subcircuit stuff * base class for other elements using internal subckts * netlist syntax: * device: Xxxxx * model: .subckt * (device cards) * .ends * storage note ... * the .subckt always has a comment at the hook point, so a for loop works * the expansion (attact to the X) has all comments removed * - need to process the entire ring - for doesn't work */ //testing=script 2006.07.17 #include "d_subckt.h" /*--------------------------------------------------------------------------*/ int DEV_SUBCKT::_count = -1; int COMMON_SUBCKT::_count = -1; int MODEL_SUBCKT::_count = -1; static COMMON_SUBCKT Default_SUBCKT(CC_STATIC); /*--------------------------------------------------------------------------*/ static DEV_SUBCKT p1; static MODEL_SUBCKT p2; static DISPATCHER::INSTALL d1(&device_dispatcher, "X|dev_subckt", &p1), d2(&device_dispatcher, "subckt|macro", &p2); /*--------------------------------------------------------------------------*/ bool COMMON_SUBCKT::operator==(const COMMON_COMPONENT& x)const { const COMMON_SUBCKT* p = dynamic_cast(&x); bool rv = p && _params == p->_params && COMMON_COMPONENT::operator==(x); return rv; } /*--------------------------------------------------------------------------*/ bool COMMON_SUBCKT::param_is_printable(int i)const { assert(i < COMMON_SUBCKT::param_count()); if (i >= COMMON_COMPONENT::param_count()) { return _params.is_printable(COMMON_SUBCKT::param_count() - 1 - i); }else{ return COMMON_COMPONENT::param_is_printable(i); } } /*--------------------------------------------------------------------------*/ std::string COMMON_SUBCKT::param_name(int i)const { assert(i < COMMON_SUBCKT::param_count()); if (i >= COMMON_COMPONENT::param_count()) { return _params.name(COMMON_SUBCKT::param_count() - 1 - i); }else{ return COMMON_COMPONENT::param_name(i); } } /*--------------------------------------------------------------------------*/ std::string COMMON_SUBCKT::param_name(int i, int j)const { assert(i < COMMON_SUBCKT::param_count()); if (j == 0) {untested(); return param_name(i); }else if (i >= COMMON_COMPONENT::param_count()) {untested(); return ""; }else{untested(); return COMMON_COMPONENT::param_name(i); } } /*--------------------------------------------------------------------------*/ std::string COMMON_SUBCKT::param_value(int i)const { assert(i < COMMON_SUBCKT::param_count()); if (i >= COMMON_COMPONENT::param_count()) { return _params.value(COMMON_SUBCKT::param_count() - 1 - i); }else{ return COMMON_COMPONENT::param_value(i); } } /*--------------------------------------------------------------------------*/ void COMMON_SUBCKT::precalc_first(const CARD_LIST* Scope) { assert(Scope); COMMON_COMPONENT::precalc_first(Scope); for (PARAM_LIST::iterator i = _params.begin(); i != _params.end(); ++i) { i->second.e_val(NOT_INPUT,Scope); } _mfactor = _params.deep_lookup("m"); } /*--------------------------------------------------------------------------*/ void COMMON_SUBCKT::precalc_last(const CARD_LIST* Scope) { assert(Scope); COMMON_COMPONENT::precalc_last(Scope); } /*--------------------------------------------------------------------------*/ MODEL_SUBCKT::MODEL_SUBCKT() :COMPONENT() { _n = _nodes; new_subckt(); ++_count; } /*--------------------------------------------------------------------------*/ MODEL_SUBCKT::MODEL_SUBCKT(const MODEL_SUBCKT& p) :COMPONENT(p) { for (int ii = 0; ii < max_nodes(); ++ii) { _nodes[ii] = p._nodes[ii]; } _n = _nodes; assert(p.subckt()->is_empty()); // incomplete, but enough for now. new_subckt(); ++_count; } /*--------------------------------------------------------------------------*/ MODEL_SUBCKT::~MODEL_SUBCKT() { --_count; } /*--------------------------------------------------------------------------*/ CARD* MODEL_SUBCKT::clone_instance()const {itested(); DEV_SUBCKT* new_instance = dynamic_cast(p1.clone()); new_instance->_parent = this; return new_instance; } /*--------------------------------------------------------------------------*/ DEV_SUBCKT::DEV_SUBCKT() :BASE_SUBCKT(), _parent(NULL) { attach_common(&Default_SUBCKT); _n = _nodes; ++_count; } /*--------------------------------------------------------------------------*/ DEV_SUBCKT::DEV_SUBCKT(const DEV_SUBCKT& p) :BASE_SUBCKT(p), _parent(p._parent) { //strcpy(modelname, p.modelname); in common for (int ii = 0; ii < max_nodes(); ++ii) { _nodes[ii] = p._nodes[ii]; } _n = _nodes; ++_count; } /*--------------------------------------------------------------------------*/ void DEV_SUBCKT::expand() { BASE_SUBCKT::expand(); COMMON_SUBCKT* c = prechecked_cast(mutable_common()); assert(c); const CARD* model = find_looking_out(c->modelname()); if (!_parent) { if(!dynamic_cast(model)) { throw Exception_Type_Mismatch(long_label(), c->modelname(), "subckt"); }else{ _parent = prechecked_cast(model); } }else{ assert(model && model == _parent); } //assert(!c->_params._try_again); assert(model->subckt()); assert(model->subckt()->params()); PARAM_LIST* pl = const_cast(model->subckt()->params()); assert(pl); c->_params.set_try_again(pl); assert(c->_params._try_again); renew_subckt(model, this, scope(), &(c->_params)); subckt()->expand(); } /*--------------------------------------------------------------------------*/ void DEV_SUBCKT::precalc_first() { BASE_SUBCKT::precalc_first(); if (subckt()) { COMMON_SUBCKT* c = prechecked_cast(mutable_common()); assert(c); subckt()->attach_params(&(c->_params), scope()); subckt()->precalc_first(); }else{ } assert(!is_constant()); /* because I have more work to do */ } /*--------------------------------------------------------------------------*/ void DEV_SUBCKT::precalc_last() { BASE_SUBCKT::precalc_last(); COMMON_SUBCKT* c = prechecked_cast(mutable_common()); assert(c); subckt()->attach_params(&(c->_params), scope()); subckt()->precalc_last(); assert(!is_constant()); /* because I have more work to do */ } /*--------------------------------------------------------------------------*/ double DEV_SUBCKT::tr_probe_num(const std::string& x)const {itested(); if (Umatch(x, "p ")) {untested(); double power = 0.; assert(subckt()); for (CARD_LIST::const_iterator ci = subckt()->begin(); ci != subckt()->end(); ++ci) {untested(); power += CARD::probe(*ci,"P"); } return power; }else if (Umatch(x, "pd ")) {untested(); double power = 0.; assert(subckt()); for (CARD_LIST::const_iterator ci = subckt()->begin(); ci != subckt()->end(); ++ci) {untested(); power += CARD::probe(*ci,"PD"); } return power; }else if (Umatch(x, "ps ")) {untested(); double power = 0.; assert(subckt()); for (CARD_LIST::const_iterator ci = subckt()->begin(); ci != subckt()->end(); ++ci) {untested(); power += CARD::probe(*ci,"PS"); } return power; }else{itested(); return COMPONENT::tr_probe_num(x); } /*NOTREACHED*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_subckt.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000011471�11454012162�0013614�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_subckt.h,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * data structures for subcircuits */ //testing=script,sparse 2006.07.17 #ifndef D_SUBCKT_H #define D_SUBCKT_H #include "e_node.h" #include "e_subckt.h" /*--------------------------------------------------------------------------*/ #define PORTS_PER_SUBCKT 100 //BUG// fixed limit on number of ports /*--------------------------------------------------------------------------*/ class INTERFACE MODEL_SUBCKT : public COMPONENT { private: explicit MODEL_SUBCKT(const MODEL_SUBCKT&p); public: explicit MODEL_SUBCKT(); ~MODEL_SUBCKT(); public: // override virtual char id_letter()const {untested();return '\0';} CARD* clone_instance()const; bool print_type_in_spice()const {unreachable(); return false;} std::string value_name()const {incomplete(); return "";} std::string dev_type()const {untested(); return "";} int max_nodes()const {return PORTS_PER_SUBCKT;} int min_nodes()const {return 0;} int matrix_nodes()const {untested();return 0;} int net_nodes()const {return _net_nodes;} CARD* clone()const {return new MODEL_SUBCKT(*this);} bool is_device()const {return false;} void precalc_first() {} void expand() {} void precalc_last() {} bool makes_own_scope()const {return true;} void map_nodes() {} CARD_LIST* scope() {return subckt();} const CARD_LIST* scope()const {return subckt();} std::string port_name(int)const { return ""; } public: static int count() {return _count;} private: node_t _nodes[PORTS_PER_SUBCKT]; static int _count; }; /*--------------------------------------------------------------------------*/ class DEV_SUBCKT : public BASE_SUBCKT { friend class MODEL_SUBCKT; private: explicit DEV_SUBCKT(const DEV_SUBCKT&); public: explicit DEV_SUBCKT(); ~DEV_SUBCKT() {--_count;} private: // override virtual char id_letter()const {return 'X';} bool print_type_in_spice()const {return true;} std::string value_name()const {return "#";} int max_nodes()const {return PORTS_PER_SUBCKT;} int min_nodes()const {return 0;} int matrix_nodes()const {return 0;} int net_nodes()const {return _net_nodes;} CARD* clone()const {return new DEV_SUBCKT(*this);} void precalc_first(); void expand(); void precalc_last(); double tr_probe_num(const std::string&)const; int param_count_dont_print()const {return common()->COMMON_COMPONENT::param_count();} std::string port_name(int i)const {itested(); if (_parent) {itested(); return _parent->port_value(i); }else{itested(); return ""; } } public: static int count() {return _count;} private: const MODEL_SUBCKT* _parent; node_t _nodes[PORTS_PER_SUBCKT]; static int _count; }; /*--------------------------------------------------------------------------*/ class INTERFACE COMMON_SUBCKT : public COMMON_COMPONENT { private: explicit COMMON_SUBCKT(const COMMON_SUBCKT& p) :COMMON_COMPONENT(p), _params(p._params) {++_count;} public: explicit COMMON_SUBCKT(int c=0) :COMMON_COMPONENT(c) {++_count;} ~COMMON_SUBCKT() {--_count;} bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new COMMON_SUBCKT(*this);} std::string name()const {itested(); return "subckt";} static int count() {return _count;} void set_param_by_name(std::string Name, std::string Value) {_params.set(Name, Value);} bool param_is_printable(int)const; std::string param_name(int)const; std::string param_name(int,int)const; std::string param_value(int)const; int param_count()const {return (static_cast(_params.size()) + COMMON_COMPONENT::param_count());} void precalc_first(const CARD_LIST*); void precalc_last(const CARD_LIST*); private: static int _count; public: PARAM_LIST _params; }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_switch.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000050734�11454012162�0013765�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_switch.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * voltage (and current) controlled switch. * netlist syntax: * device: Sxxxx n+ n- vc+ vc- mname | * model: .model mname SW * current controlled switch * device: Wxxxx n+ n- controlelement mname | * model: .model mname CSW */ //testing=script 2006.06.14 #include "e_model.h" #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ enum state_t {_UNKNOWN, _ON, _OFF}; /*--------------------------------------------------------------------------*/ class COMMON_SWITCH : public COMMON_COMPONENT { private: explicit COMMON_SWITCH(const COMMON_SWITCH& p) :COMMON_COMPONENT(p), _ic(p._ic) {} public: explicit COMMON_SWITCH(int c=0) :COMMON_COMPONENT(c), _ic(_UNKNOWN) {} bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new COMMON_SWITCH(*this);} std::string name()const {untested(); return "switch";} bool param_is_printable(int)const; std::string param_name(int)const; std::string param_name(int,int)const; std::string param_value(int)const; int param_count()const {return (1 + COMMON_COMPONENT::param_count());} public: state_t _ic; /* initial state, belongs in common */ //BUG// no way to set _ic }; /*--------------------------------------------------------------------------*/ class SWITCH_BASE : public ELEMENT { protected: explicit SWITCH_BASE(); explicit SWITCH_BASE(const SWITCH_BASE& p); protected: // override virtual std::string value_name()const {return "";} std::string dev_type()const {assert(common()); return common()->modelname().c_str();} bool print_type_in_spice()const {return true;} int tail_size()const {return 1;} int max_nodes()const = 0; int min_nodes()const = 0; int matrix_nodes()const {return 2;} int net_nodes()const = 0; CARD* clone()const = 0; void expand(); void precalc_last(); void tr_iwant_matrix() {tr_iwant_matrix_passive();} void tr_begin(); void dc_advance(); void tr_advance(); void tr_regress(); bool tr_needs_eval()const {return _sim->analysis_is_static();} // also q by tr_advance bool do_tr(); void tr_load() {tr_load_passive();} TIME_PAIR tr_review(); void tr_unload() {untested(); tr_unload_passive();} double tr_involts()const {untested(); return tr_outvolts();} double tr_involts_limited()const {unreachable(); return tr_outvolts_limited();} void ac_iwant_matrix() {ac_iwant_matrix_passive();} void ac_begin() {_ev = _y[0].f1; _acg = _m0.c1;} void do_ac(); void ac_load() {ac_load_passive();} COMPLEX ac_involts()const {untested(); return ac_outvolts();} protected: const ELEMENT* _input; private: double _in[OPT::_keep_time_steps]; state_t _state[OPT::_keep_time_steps]; }; /*--------------------------------------------------------------------------*/ class DEV_VSWITCH : public SWITCH_BASE { private: explicit DEV_VSWITCH(const DEV_VSWITCH& p) :SWITCH_BASE(p) {} public: explicit DEV_VSWITCH() :SWITCH_BASE() {} private: // override virtual int max_nodes()const {return 4;} int min_nodes()const {return 4;} int net_nodes()const {return 4;} CARD* clone()const {return new DEV_VSWITCH(*this);} char id_letter()const {return 'S';} std::string port_name(int i)const {itested(); assert(i >= 0); assert(i < 4); static std::string names[] = {"p", "n", "ps", "ns"}; return names[i]; } }; /*--------------------------------------------------------------------------*/ class DEV_CSWITCH : public SWITCH_BASE { private: explicit DEV_CSWITCH(const DEV_CSWITCH& p) :SWITCH_BASE(p), _input_label(p._input_label) {} public: explicit DEV_CSWITCH() :SWITCH_BASE(), _input_label() {} private: // override virtual int max_nodes()const {return 3;} int ext_nodes()const {return 2;} int min_nodes()const {return 3;} int net_nodes()const {return 2;} int num_current_ports()const {return 1;} const std::string current_port_value(int)const {return _input_label;}; CARD* clone()const {return new DEV_CSWITCH(*this);} void expand(); char id_letter()const {return 'W';} void set_port_by_name(std::string& Name, std::string& Value) {untested(); SWITCH_BASE::set_port_by_name(Name,Value);} void set_port_by_index(int, std::string&); bool node_is_connected(int)const; std::string port_name(int i)const {itested(); assert(i >= 0); assert(i < 2); static std::string names[] = {"p", "n"}; return names[i]; } std::string current_port_name(int i)const { assert(i >= 0); assert(i < 1); static std::string names[] = {"in"}; return names[i]; } private: std::string _input_label; }; /*--------------------------------------------------------------------------*/ class MODEL_SWITCH : public MODEL_CARD { private: explicit MODEL_SWITCH(const MODEL_SWITCH& p); public: explicit MODEL_SWITCH(const SWITCH_BASE*); private: // override virtual void set_dev_type(const std::string& nt); std::string dev_type()const; CARD* clone()const {return new MODEL_SWITCH(*this);} void precalc_first(); void set_param_by_index(int, std::string&, int); bool param_is_printable(int)const; std::string param_name(int)const; std::string param_name(int,int)const; std::string param_value(int)const; int param_count()const {return (6 + MODEL_CARD::param_count());} public: PARAMETER vt; /* threshold voltage */ PARAMETER vh; /* hysteresis voltage */ PARAMETER ron; /* on resistance */ PARAMETER roff; /* off resistance */ PARAMETER von; PARAMETER voff; enum control_t {VOLTAGE, CURRENT}; control_t type; /* current or voltage controlled */ private: static double const _default_vt; static double const _default_vh; static double const _default_ron; static double const _default_roff; }; /*--------------------------------------------------------------------------*/ static COMMON_SWITCH Default_SWITCH(CC_STATIC); double const MODEL_SWITCH::_default_vt = 0.; double const MODEL_SWITCH::_default_vh = 0.; double const MODEL_SWITCH::_default_ron = 1.; double const MODEL_SWITCH::_default_roff = 1e12; /*--------------------------------------------------------------------------*/ bool COMMON_SWITCH::operator==(const COMMON_COMPONENT& x)const { const COMMON_SWITCH* p = dynamic_cast(&x); return p && COMMON_COMPONENT::operator==(x); } /*--------------------------------------------------------------------------*/ bool COMMON_SWITCH::param_is_printable(int i)const { switch (COMMON_SWITCH::param_count() - 1 - i) { case 0: return (_ic == _ON || _ic == _OFF); default: return COMMON_COMPONENT::param_is_printable(i); } } /*--------------------------------------------------------------------------*/ std::string COMMON_SWITCH::param_name(int i)const { switch (COMMON_SWITCH::param_count() - 1 - i) { case 0: return "ic"; default: return COMMON_COMPONENT::param_name(i); } } /*--------------------------------------------------------------------------*/ std::string COMMON_SWITCH::param_name(int i, int j)const {itested(); if (j == 0) {itested(); return param_name(i); }else if (i >= COMMON_COMPONENT::param_count()) {itested(); return ""; }else{itested(); return COMMON_COMPONENT::param_name(i, j); } } /*--------------------------------------------------------------------------*/ std::string COMMON_SWITCH::param_value(int i)const {itested(); switch (COMMON_SWITCH::param_count() - 1 - i) { case 0: return (_ic == _ON) ? "1" : "0"; default: return COMMON_COMPONENT::param_value(i); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ MODEL_SWITCH::MODEL_SWITCH(const SWITCH_BASE* p) :MODEL_CARD(p), vt(_default_vt), vh(_default_vh), ron(_default_ron), roff(_default_roff), von(_default_vt + _default_vh), voff(_default_vt - _default_vh), type(VOLTAGE) { } /*--------------------------------------------------------------------------*/ MODEL_SWITCH::MODEL_SWITCH(const MODEL_SWITCH& p) :MODEL_CARD(p), vt(p.vt), vh(p.vh), ron(p.ron), roff(p.roff), von(p.von), voff(p.voff), type(p.type) { } /*--------------------------------------------------------------------------*/ void MODEL_SWITCH::set_dev_type(const std::string& new_type) { if (new_type == "sw") { type = VOLTAGE; }else if (new_type == "csw") { type = CURRENT; }else{ MODEL_CARD::set_dev_type(new_type); } } /*--------------------------------------------------------------------------*/ void MODEL_SWITCH::precalc_first() { MODEL_CARD::precalc_first(); const CARD_LIST* par_scope = scope(); assert(par_scope); vt.e_val(_default_vt, par_scope); vh.e_val(_default_vh, par_scope); ron.e_val(_default_ron, par_scope); roff.e_val(_default_roff, par_scope); von.e_val(vt + vh, par_scope); voff.e_val(vt - vh, par_scope); } /*--------------------------------------------------------------------------*/ std::string MODEL_SWITCH::dev_type()const { switch (type) { case VOLTAGE: return "sw"; break; case CURRENT: return "csw"; break; } unreachable(); return ""; } /*--------------------------------------------------------------------------*/ void MODEL_SWITCH::set_param_by_index(int i, std::string& value, int offset) { switch (MODEL_SWITCH::param_count() - 1 - i) { case 0: vt = value; break; case 1: vh = value; break; case 2: von = value; break; case 3: voff = value; break; case 4: ron = value; break; case 5: roff = value; break; default: MODEL_CARD::set_param_by_index(i, value, offset); break; } } /*--------------------------------------------------------------------------*/ bool MODEL_SWITCH::param_is_printable(int i)const { switch (MODEL_SWITCH::param_count() - 1 - i) { case 0: case 1: case 2: case 3: case 4: case 5: return true; default: return MODEL_CARD::param_is_printable(i); } } /*--------------------------------------------------------------------------*/ std::string MODEL_SWITCH::param_name(int i)const { switch (type) { case VOLTAGE: switch (MODEL_SWITCH::param_count() - 1 - i) { case 0: return "vt"; case 1: return "vh"; case 2: return "von"; case 3: return "voff"; case 4: return "ron"; case 5: return "roff"; default: return MODEL_CARD::param_name(i); } case CURRENT: switch (MODEL_SWITCH::param_count() - 1 - i) { case 0: return "it"; case 1: return "ih"; case 2: return "ion"; case 3: return "ioff"; case 4: return "ron"; case 5: return "roff"; default: return MODEL_CARD::param_name(i); } } unreachable(); return ""; } /*--------------------------------------------------------------------------*/ std::string MODEL_SWITCH::param_name(int i, int j)const { if (j == 0) { return param_name(i); }else if (i >= MODEL_CARD::param_count()) { return ""; }else{ return MODEL_CARD::param_name(i, j); } } /*--------------------------------------------------------------------------*/ std::string MODEL_SWITCH::param_value(int i)const { switch (MODEL_SWITCH::param_count() - 1 - i) { case 0: return vt.string(); case 1: return vh.string(); case 2: return von.string(); case 3: return voff.string(); case 4: return ron.string(); case 5: return roff.string(); default: return MODEL_CARD::param_value(i); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ SWITCH_BASE::SWITCH_BASE() :ELEMENT(), _input(NULL) { attach_common(&Default_SWITCH); std::fill_n(_in, int(OPT::_keep_time_steps), 0.); std::fill_n(_state, int(OPT::_keep_time_steps), _UNKNOWN); } /*--------------------------------------------------------------------------*/ SWITCH_BASE::SWITCH_BASE(const SWITCH_BASE& p) :ELEMENT(p), _input(NULL) { notstd::copy_n(p._in, int(OPT::_keep_time_steps), _in); notstd::copy_n(p._state, int(OPT::_keep_time_steps), _state); } /*--------------------------------------------------------------------------*/ void SWITCH_BASE::expand() { ELEMENT::expand(); attach_model(); const COMMON_SWITCH* c = dynamic_cast(common()); assert(c); const MODEL_SWITCH* m = dynamic_cast(c->model()); if (!m) { assert(has_common()); throw Exception_Model_Type_Mismatch(long_label(), common()->modelname(), "switch (SW or CSW)"); }else{ } } /*--------------------------------------------------------------------------*/ void SWITCH_BASE::precalc_last() { ELEMENT::precalc_last(); if (_sim->is_first_expand()) { const COMMON_SWITCH* c = prechecked_cast(common()); assert(c); const MODEL_SWITCH* m = prechecked_cast(c->model()); assert(m); _y1.f1 = _y[0].f1 = (c->_ic == _ON) ? m->ron : m->roff; // override, unknown is off assert(!is_constant()); // depends on input // converged????? _m0.c1 = 1./_y[0].f1; _m0.c0 = 0.; _m1 = _m0; _state[1] = _state[0] = c->_ic; }else{ } assert(_loss0 == 0.); assert(_loss1 == 0.); } /*--------------------------------------------------------------------------*/ void SWITCH_BASE::tr_begin() { ELEMENT::tr_begin(); const COMMON_SWITCH* c = prechecked_cast(common()); assert(c); const MODEL_SWITCH* m = prechecked_cast(c->model()); assert(m); assert(_loss0 == 0.); assert(_loss1 == 0.); assert(_y[0].f0 == LINEAR); _y1.f1 = _y[0].f1 = ((c->_ic == _ON) ? m->ron : m->roff); /* unknown is off */ _m0.c1 = 1./_y[0].f1; assert(_m0.c0 == 0.); _m1 = _m0; _state[1] = _state[0] = c->_ic; set_converged(); } /*--------------------------------------------------------------------------*/ void SWITCH_BASE::dc_advance() { ELEMENT::dc_advance(); _state[1] = _state[0]; } /*--------------------------------------------------------------------------*/ void SWITCH_BASE::tr_advance() { ELEMENT::tr_advance(); const COMMON_SWITCH* c = prechecked_cast(common()); assert(c); const MODEL_SWITCH* m = prechecked_cast(c->model()); assert(m); _state[1] = _state[0]; _y[0].x = _in[1] = _in[0]; if (_y[0].x >= m->von) { _state[0] = _ON; }else if (_y[0].x <= m->voff) { _state[0] = _OFF; }else{ _state[0] = _state[1]; } if (_state[1] != _state[0]) { _y[0].f1 = (_state[0] == _ON) ? m->ron : m->roff; /* unknown is off */ _m0.c1 = 1./_y[0].f1; q_eval(); }else{ } assert(_y[0].f1 == ((_state[0] == _ON) ? m->ron : m->roff)); assert(_y[0].f0 == LINEAR); trace4("", _m0.c1, 1./_y[0].f1, ((_m0.c1) - (1./_y[0].f1)), ((_m0.c1) / (1./_y[0].f1))); assert(conchk(_m0.c1, 1./_y[0].f1)); assert(_m0.c0 == 0.); set_converged(); } /*--------------------------------------------------------------------------*/ void SWITCH_BASE::tr_regress() { ELEMENT::tr_regress(); const COMMON_SWITCH* c = prechecked_cast(common()); assert(c); const MODEL_SWITCH* m = prechecked_cast(c->model()); assert(m); assert(_y[0].f1 == ((_state[0] == _ON) ? m->ron : m->roff)); assert(_y[0].f0 == LINEAR); assert(_m0.c1 == 1./_y[0].f1); assert(_m0.c0 == 0.); set_converged(); } /*--------------------------------------------------------------------------*/ bool SWITCH_BASE::do_tr() { const COMMON_SWITCH* c = prechecked_cast(common()); assert(c); const MODEL_SWITCH* m = prechecked_cast(c->model()); assert(m); if (_sim->analysis_is_static()) { _y[0].x = (_input) /* _y[0].x is controlling value */ ? CARD::probe(_input,"I") /* current controlled */ : _n[IN1].v0() - _n[IN2].v0(); /* voltage controlled */ state_t new_state; if (_y[0].x > m->von) { new_state = _ON; }else if (_y[0].x < m->voff) { new_state = _OFF; }else{ new_state = _state[1]; } if (new_state != _state[0]) { _y[0].f1 = (new_state == _ON) ? m->ron : m->roff; /* unknown is off */ _state[0] = new_state; _m0.c1 = 1./_y[0].f1; trace4("change", new_state, old_state, _y[0].f1, _m0.c1); q_load(); store_values(); set_not_converged(); }else{ trace3("no change", new_state, _y[0].f1, _m0.c1); set_converged(); } }else{ // Above isn't necessary because it was done in tr_advance, // and doesn't iterate. // I believe it is not necessary on restart, because it is stored. if (_state[0] != _state[1]) { q_load(); store_values(); }else{ // gets here only on "nobypass" } assert(converged()); } assert(_y[0].f1 == ((_state[0] == _ON) ? m->ron : m->roff)); assert(_y[0].f0 == LINEAR); //assert(_m0.c1 == 1./_y[0].f1); assert(_m0.c0 == 0.); return converged(); } /*--------------------------------------------------------------------------*/ TIME_PAIR SWITCH_BASE::tr_review() { ELEMENT::tr_review(); const COMMON_SWITCH* c = prechecked_cast(common()); assert(c); const MODEL_SWITCH* m = prechecked_cast(c->model()); assert(m); _in[0] = (_input) ? CARD::probe(_input,"I") : _n[IN1].v0() - _n[IN2].v0(); double old_dt = _time[0] - _time[1]; double old_dv = _in[0] - _in[1]; if (_state[0] != _ON && old_dv > 0) { double new_dv = m->von - _in[1]; double new_dt = old_dt * new_dv / old_dv; _time_by.min_event(_time[1] + new_dt); }else if (_state[0] != _OFF && old_dv < 0) { double new_dv = m->voff - _in[1]; double new_dt = old_dt * new_dv / old_dv; _time_by.min_event(_time[1] + new_dt); }else{ assert(_time_by._event == NEVER); } // _time_by_event is the predicted switch time return _time_by; } /*--------------------------------------------------------------------------*/ void SWITCH_BASE::do_ac() { assert(_ev == _y[0].f1); assert(_acg == _m0.c1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void DEV_CSWITCH::expand() { SWITCH_BASE::expand(); _input = dynamic_cast(find_in_my_scope(_input_label)); if (!_input) { throw Exception(long_label() + ": " + _input_label + " cannot be used as input"); }else{ } } /*--------------------------------------------------------------------------*/ void DEV_CSWITCH::set_port_by_index(int Num, std::string& Value) { if (Num == 2) { _input_label = Value; }else{ SWITCH_BASE::set_port_by_index(Num, Value); } } /*--------------------------------------------------------------------------*/ bool DEV_CSWITCH::node_is_connected(int i)const { if (i == 2) { return _input_label != ""; }else{ return SWITCH_BASE::node_is_connected(i); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_VSWITCH p2; DEV_CSWITCH p3; DISPATCHER::INSTALL d2(&device_dispatcher, "S|vswitch", &p2), d3(&device_dispatcher, "W|cswitch|iswitch", &p3); MODEL_SWITCH p1(&p2); MODEL_SWITCH p4(&p3); DISPATCHER::INSTALL d1(&model_dispatcher, "sw", &p1), d4(&model_dispatcher, "csw", &p4); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ������������������������������������src/d_trln.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000044303�11454012162�0013436�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_trln.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Transmission line. (ideal lossless.) */ //testing=script,sparse 2006.07.17 #include "m_wave.h" #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ enum {NUM_INIT_COND = 4}; /*--------------------------------------------------------------------------*/ class COMMON_TRANSLINE : public COMMON_COMPONENT { private: PARAMETER len; /* length multiplier */ PARAMETER R; PARAMETER L; PARAMETER G; PARAMETER C; PARAMETER z0; /* characteristic impedance */ PARAMETER td; /* delay time */ PARAMETER f; /* specification frequency */ PARAMETER nl; /* length (wavelengths) at f */ double ic[NUM_INIT_COND]; /* initial conditions: v1, i1, v2, i2 */ int icset; /* flag: initial condition set */ public: double real_z0; double real_td; private: explicit COMMON_TRANSLINE(const COMMON_TRANSLINE& p); public: explicit COMMON_TRANSLINE(int c=0); bool operator==(const COMMON_COMPONENT&)const; COMMON_COMPONENT* clone()const {return new COMMON_TRANSLINE(*this);} void set_param_by_index(int, std::string&, int); bool param_is_printable(int)const; std::string param_name(int)const; std::string param_name(int,int)const; std::string param_value(int)const; int param_count()const {return (9 + COMMON_COMPONENT::param_count());} public: void precalc_first(const CARD_LIST*); void precalc_last(const CARD_LIST*); std::string name()const {untested(); return "transline";} }; /*--------------------------------------------------------------------------*/ class DEV_TRANSLINE : public ELEMENT { private: WAVE _forward; WAVE _reflect; double _if0; // value of current source representing incident wave double _ir0; // value of current source representing reflected wave double _if1; // val of cs rep incident wave, one load ago double _ir1; // val of cs rep reflected wave, one load ago COMPLEX _y11;// AC equiv ckt COMPLEX _y12;// AC equiv ckt private: explicit DEV_TRANSLINE(const DEV_TRANSLINE& p) :ELEMENT(p), _forward(), _reflect(), _if0(0), _ir0(0), _if1(0), _ir1(0) {} public: explicit DEV_TRANSLINE(); private: // override virtual char id_letter()const {return 'T';} std::string value_name()const {return "#";} std::string dev_type()const {itested(); return "tline";} int max_nodes()const {return 4;} int min_nodes()const {return 4;} int matrix_nodes()const {return 4;} int net_nodes()const {return 4;} CARD* clone()const {return new DEV_TRANSLINE(*this);} void precalc_last(); void tr_iwant_matrix(); void tr_begin(); void dc_advance(); void tr_advance(); void tr_regress(); bool tr_needs_eval()const; bool do_tr(); void tr_load(); TIME_PAIR tr_review(); void tr_accept(); void tr_unload(); double tr_involts()const; double tr_involts_limited()const; void ac_iwant_matrix() {ac_iwant_matrix_extended();} void do_ac(); void ac_load(); COMPLEX ac_involts()const; std::string port_name(int i)const {itested(); assert(i >= 0); assert(i < 4); static std::string names[] = {"t1", "b1", "t2", "b2"}; return names[i]; } private: void setinitcond(CS&); }; /*--------------------------------------------------------------------------*/ inline bool DEV_TRANSLINE::tr_needs_eval()const { assert(!is_q_for_eval()); return (_if0!=_if1 || _ir0!=_ir1); } /*--------------------------------------------------------------------------*/ inline double DEV_TRANSLINE::tr_involts()const { return dn_diff(_n[IN1].v0(), _n[IN2].v0()); } /*--------------------------------------------------------------------------*/ inline double DEV_TRANSLINE::tr_involts_limited()const { unreachable(); return volts_limited(_n[IN1],_n[IN2]); } /*--------------------------------------------------------------------------*/ inline COMPLEX DEV_TRANSLINE::ac_involts()const {untested(); return _n[IN1]->vac() - _n[IN2]->vac(); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ const double _default_len (1); const double _default_R (0); const double _default_L (NOT_INPUT); const double _default_G (0); const double _default_C (NOT_INPUT); const double _default_z0 (50.); const double _default_td (NOT_INPUT); const double _default_f (NOT_INPUT); const double _default_nl (0.25); const double LINLENTOL = .000001; static COMMON_TRANSLINE Default_TRANSLINE(CC_STATIC); /*--------------------------------------------------------------------------*/ COMMON_TRANSLINE::COMMON_TRANSLINE(int c) :COMMON_COMPONENT(c), len(_default_len), R(_default_R), L(_default_L), G(_default_G), C(_default_C), z0(_default_z0), td(_default_td), f(_default_f), nl(_default_nl), icset(false), real_z0(NOT_INPUT), real_td(NOT_INPUT) { for (int i = 0; i < NUM_INIT_COND; ++i) { ic[i] = 0.; } } /*--------------------------------------------------------------------------*/ COMMON_TRANSLINE::COMMON_TRANSLINE(const COMMON_TRANSLINE& p) :COMMON_COMPONENT(p), len(p.len), R(p.R), L(p.L), G(p.G), C(p.C), z0(p.z0), td(p.td), f(p.f), nl(p.nl), icset(p.icset), real_z0(p.real_z0), real_td(p.real_td) { for (int i = 0; i < NUM_INIT_COND; ++i) { ic[i] = p.ic[i]; } } /*--------------------------------------------------------------------------*/ bool COMMON_TRANSLINE::operator==(const COMMON_COMPONENT& x)const { const COMMON_TRANSLINE* p = dynamic_cast(&x); bool rv = p && len == p->len && R == p->R && L == p->L && G == p->G && C == p->C && z0 == p->z0 && td == p->td && f == p->f && nl == p->nl && icset == p->icset && COMMON_COMPONENT::operator==(x); if (rv) { for (int i=0; iic[i]; } }else{ } return rv; } /*--------------------------------------------------------------------------*/ void COMMON_TRANSLINE::set_param_by_index(int I, std::string& Value, int Offset) { switch (COMMON_TRANSLINE::param_count() - 1 - I) { case 0: len = Value; break; case 1: R = Value; break; case 2: L = Value; break; case 3: G = Value; break; case 4: C = Value; break; case 5: z0 = Value; break; case 6: td = Value; break; case 7: f = Value; break; case 8: nl = Value; break; default: COMMON_COMPONENT::set_param_by_index(I, Value, Offset); break; } //BUG// does not print IC } /*--------------------------------------------------------------------------*/ bool COMMON_TRANSLINE::param_is_printable(int I)const { switch (COMMON_TRANSLINE::param_count() - 1 - I) { case 0: return len.has_hard_value(); case 1: return R.has_hard_value(); case 2: return L.has_hard_value(); case 3: return G.has_hard_value(); case 4: return C.has_hard_value(); case 5: return z0.has_hard_value(); case 6: return td.has_hard_value(); case 7: return f.has_hard_value(); case 8: return nl.has_hard_value(); default: return COMMON_COMPONENT::param_is_printable(I); } //BUG// does not print IC #if 0 if (icset) {untested(); o << " IC="; for (int i = 0; i < NUM_INIT_COND; ++i) {untested(); o << ic[i] << ' '; } }else{ } #endif } /*--------------------------------------------------------------------------*/ std::string COMMON_TRANSLINE::param_name(int I)const { switch (COMMON_TRANSLINE::param_count() - 1 - I) { case 0: return "len"; case 1: return "r"; case 2: return "l"; case 3: return "g"; case 4: return "c"; case 5: return "z0"; case 6: return "td"; case 7: return "f"; case 8: return "nl"; default: return COMMON_COMPONENT::param_name(I); } //BUG// does not print IC } /*--------------------------------------------------------------------------*/ std::string COMMON_TRANSLINE::param_name(int I, int j)const { if (j == 0) { return param_name(I); }else if (I >= COMMON_COMPONENT::param_count()) { switch (COMMON_TRANSLINE::param_count() - 1 - I) { case 5: return (j==1) ? "z" : (j==2) ? "zo" : ""; case 6: return (j==1) ? "d" : (j==2) ? "delay" : ""; case 7: return (j==1) ? "freq" : ""; default: return ""; } }else{ return COMMON_COMPONENT::param_name(I, j); } //BUG// does not print IC } /*--------------------------------------------------------------------------*/ std::string COMMON_TRANSLINE::param_value(int I)const { switch (COMMON_TRANSLINE::param_count() - 1 - I) { case 0: return len.string(); case 1: return R.string(); case 2: return L.string(); case 3: return G.string(); case 4: return C.string(); case 5: return z0.string(); case 6: return td.string(); case 7: return f.string(); case 8: return nl.string(); default: return COMMON_COMPONENT::param_value(I); } //BUG// does not print IC } /*--------------------------------------------------------------------------*/ void COMMON_TRANSLINE::precalc_first(const CARD_LIST* Scope) { assert(Scope); COMMON_COMPONENT::precalc_first(Scope); len.e_val(_default_len, Scope); R.e_val(_default_R, Scope); L.e_val(_default_L, Scope); G.e_val(_default_G, Scope); C.e_val(_default_C, Scope); z0.e_val(_default_z0, Scope); td.e_val(_default_td, Scope); f.e_val(_default_f, Scope); nl.e_val(_default_nl, Scope); } /*--------------------------------------------------------------------------*/ void COMMON_TRANSLINE::precalc_last(const CARD_LIST* Scope) { assert(Scope); COMMON_COMPONENT::precalc_last(Scope); { // real_td if (td.has_hard_value()) {untested(); real_td = len * td; if (f.has_hard_value()) {untested(); // check for conflicts if (!conchk(td, nl/f, OPT::vntol)) {untested(); error(bDANGER, "td, f&nl conflict. using td\n"); }else{untested(); } }else{untested(); } }else if (f.has_hard_value()) { real_td = len * nl / f; }else if (L.has_hard_value() && C.has_hard_value()) {untested(); real_td = len * sqrt(L * C); }else{untested(); assert(real_td == NOT_INPUT); error(bDANGER, "can't determine length\n"); } } { // real_z0 if (z0.has_hard_value()) { real_z0 = z0; if (L.has_hard_value() && C.has_hard_value()) {untested(); error(bDANGER, "redundant specification both Z0 and LC, using Z0\n"); }else{ } }else{untested(); if (L.has_hard_value() && C.has_hard_value()) {untested(); real_z0 = sqrt(L / C); }else{untested(); assert(_default_z0 == 50.); error(bDANGER, "can't determine Z0, assuming 50\n"); real_z0 = _default_z0; } } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_TRANSLINE::DEV_TRANSLINE() :ELEMENT(), _forward(), _reflect(), _if0(0), _ir0(0), _if1(0), _ir1(0), _y11(), _y12() { attach_common(&Default_TRANSLINE); } /*--------------------------------------------------------------------------*/ void DEV_TRANSLINE::precalc_last() { ELEMENT::precalc_last(); const COMMON_TRANSLINE* c=prechecked_cast(common()); assert(c); _forward.set_delay(c->real_td); _reflect.set_delay(c->real_td); set_converged(); assert(!is_constant()); } /*--------------------------------------------------------------------------*/ void DEV_TRANSLINE::tr_iwant_matrix() { _sim->_aa.iwant(_n[OUT1].m_(),_n[OUT2].m_()); _sim->_aa.iwant(_n[IN1].m_(), _n[IN2].m_()); _sim->_lu.iwant(_n[OUT1].m_(),_n[OUT2].m_()); _sim->_lu.iwant(_n[IN1].m_(), _n[IN2].m_()); } /*--------------------------------------------------------------------------*/ /* first setup, initial dc, empty the lines */ void DEV_TRANSLINE::tr_begin() { ELEMENT::tr_begin(); const COMMON_TRANSLINE* c=prechecked_cast(common()); assert(c); _forward.initialize().push(0.-c->real_td, 0.).push(0., 0.); _reflect.initialize().push(0.-c->real_td, 0.).push(0., 0.); } /*--------------------------------------------------------------------------*/ /* before anything else .. see what is coming out * _if0 = output current .. * The "wave" class stores voltages, but we need currents, * because the simulator uses the Norton equivalent circuit. * This makes the Thevenin to Norton conversion. */ void DEV_TRANSLINE::dc_advance() { ELEMENT::dc_advance(); const COMMON_TRANSLINE* c=prechecked_cast(common()); assert(c); _if0 = _forward.v_out(_sim->_time0).f0/c->real_z0; _ir0 = _reflect.v_out(_sim->_time0).f0/c->real_z0; } void DEV_TRANSLINE::tr_advance() { ELEMENT::tr_advance(); const COMMON_TRANSLINE* c=prechecked_cast(common()); assert(c); _if0 = _forward.v_out(_sim->_time0).f0/c->real_z0; _ir0 = _reflect.v_out(_sim->_time0).f0/c->real_z0; } void DEV_TRANSLINE::tr_regress() { ELEMENT::tr_regress(); const COMMON_TRANSLINE* c=prechecked_cast(common()); assert(c); _if0 = _forward.v_out(_sim->_time0).f0/c->real_z0; _ir0 = _reflect.v_out(_sim->_time0).f0/c->real_z0; } /*--------------------------------------------------------------------------*/ /* usually nothing, always converged. It is all done in advance and accept. * UNLESS ... it is a very short line .. then we fake it here. * very short line means delay is less than internal time step. */ bool DEV_TRANSLINE::do_tr() { // code to deal with short lines goes here. //if (_if0 != _if1 || _ir0 != _ir1) { if (!conchk(_if0, _if1, OPT::abstol, OPT::reltol*.01) || !conchk(_ir0, _ir1, OPT::abstol, OPT::reltol*.01)) { q_load(); }else{ } assert(converged()); return true; } /*--------------------------------------------------------------------------*/ void DEV_TRANSLINE::tr_load() { //BUG// explicit mfactor double lvf = NOT_VALID; // load value, forward double lvr = NOT_VALID; // load value, reflected if (!_sim->is_inc_mode()) { const COMMON_TRANSLINE* c = prechecked_cast(common()); assert(c); _sim->_aa.load_symmetric(_n[OUT1].m_(), _n[OUT2].m_(), mfactor()/c->real_z0); _sim->_aa.load_symmetric(_n[IN1].m_(), _n[IN2].m_(), mfactor()/c->real_z0); lvf = _if0; lvr = _ir0; }else{ lvf = dn_diff(_if0, _if1); lvr = dn_diff(_ir0, _ir1); } if (lvf != 0.) { if (_n[OUT1].m_() != 0) { _n[OUT1].i() += mfactor() * lvf; }else{untested(); } if (_n[OUT2].m_() != 0) {untested(); _n[OUT2].i() -= mfactor() * lvf; }else{ } }else{ } if (lvr != 0.) { if (_n[IN1].m_() != 0) { _n[IN1].i() += mfactor() * lvr; }else{untested(); } if (_n[IN2].m_() != 0) {untested(); _n[IN2].i() -= mfactor() * lvr; }else{ } }else{ } _if1 = _if0; _ir1 = _ir0; } /*--------------------------------------------------------------------------*/ /* limit the time step to no larger than a line length. */ TIME_PAIR DEV_TRANSLINE::tr_review() { q_accept(); const COMMON_TRANSLINE* c=prechecked_cast(common()); assert(c); return TIME_PAIR(_sim->_time0 + c->real_td, NEVER); // ok to miss the spikes, for now } /*--------------------------------------------------------------------------*/ /* after this step is all done, determine the reflections and send them on. */ void DEV_TRANSLINE::tr_accept() { trace1(short_label().c_str(), _sim->_time0); _reflect.push(_sim->_time0, _forward.v_reflect(_sim->_time0, tr_outvolts())); _forward.push(_sim->_time0, _reflect.v_reflect(_sim->_time0, tr_involts())); } /*--------------------------------------------------------------------------*/ void DEV_TRANSLINE::tr_unload() {untested(); } /*--------------------------------------------------------------------------*/ void DEV_TRANSLINE::do_ac() { const COMMON_TRANSLINE*c=prechecked_cast(common()); assert(c); double lenth = _sim->_freq * c->real_td * 4; /* length in quarter waves */ double dif = lenth - floor(lenth+.5); /* avoid divide by zero if close to */ if (std::abs(dif) < LINLENTOL) { /* resonance by tweeking a little */ error(bDEBUG, long_label() + ": transmission line too close to resonance\n"); lenth = (dif<0.) ? floor(lenth+.5)-LINLENTOL : floor(lenth+.5)+LINLENTOL; }else{ } lenth *= (M_PI_2); /* now in radians */ _y12 = COMPLEX(0., -1. / (c->real_z0 * sin(lenth))); _y11 = COMPLEX(0., tan(lenth/2) / c->real_z0) + _y12; } /*--------------------------------------------------------------------------*/ void DEV_TRANSLINE::ac_load() { //BUG// explicit mfactor _sim->_acx.load_symmetric(_n[OUT1].m_(), _n[OUT2].m_(), mfactor()*_y11); _sim->_acx.load_symmetric(_n[IN1].m_(), _n[IN2].m_(), mfactor()*_y11); _sim->_acx.load_asymmetric(_n[OUT1].m_(),_n[OUT2].m_(), _n[IN2].m_(), _n[IN1].m_(), mfactor()*_y12); _sim->_acx.load_asymmetric(_n[IN1].m_(), _n[IN2].m_(), _n[OUT2].m_(), _n[OUT1].m_(), mfactor()*_y12); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_TRANSLINE p1; DISPATCHER::INSTALL d1(&device_dispatcher, "T|tline", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_vcg.cc����������������������������������������������������������������������������������������0000664�0000000�0000000�00000010367�11454012162�0013241�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_vcg.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * admittance devices: * self-admittance (old Y device) * y.x = volts, y.f0 = amps, ev = y.f1 = mhos. * m.x = volts, m.c0 = amps, acg = m.c1 = mhos. * trans-admittance (VCCS, G device) * voltage controlled admittance * y.x = volts(control), y.f0 = mhos, ev = y.f1 = mhos/volt * m.x = volts(control), m.c0 = 0, acg = m.c1 = mhos * _loss0 == 1/R. (mhos) */ //testing=script 2006.07.17 #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class DEV_VCG : public ELEMENT { private: explicit DEV_VCG(const DEV_VCG& p) :ELEMENT(p) {} public: explicit DEV_VCG() :ELEMENT() {} private: // override virtual char id_letter()const {untested();return '\0';} std::string value_name()const {untested(); return "g";} std::string dev_type()const {return "vcg";} int max_nodes()const {return 4;} int min_nodes()const {return 4;} int matrix_nodes()const {return 4;} int net_nodes()const {return 4;} bool use_obsolete_callback_parse()const {return true;} CARD* clone()const {return new DEV_VCG(*this);} void tr_iwant_matrix() {tr_iwant_matrix_extended();} void tr_begin(); bool do_tr(); void tr_load() {tr_load_shunt(); tr_load_active();} void tr_unload() {untested(); tr_unload_shunt(); tr_unload_active();} double tr_involts()const {return dn_diff(_n[IN1].v0(), _n[IN2].v0());} double tr_involts_limited()const {return volts_limited(_n[IN1],_n[IN2]);} void ac_iwant_matrix() {ac_iwant_matrix_extended();} void ac_begin() {_ev = _y[0].f0; _acg = _m0.c1;} void do_ac(); void ac_load() {ac_load_shunt(); ac_load_active();} COMPLEX ac_involts()const {return _n[IN1]->vac() - _n[IN2]->vac();} std::string port_name(int i)const {untested(); assert(i >= 0); assert(i < 4); static std::string names[] = {"p", "n", "ps", "ns"}; return names[i]; } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void DEV_VCG::tr_begin() { ELEMENT::tr_begin(); _y1.f0 = _y[0].f0 = 0; // override _loss1 = _loss0 = 0; _m0.x = 0.; _m0.c1 = 0.; _m0.c0 = 0.; _m1 = _m0; } /*--------------------------------------------------------------------------*/ bool DEV_VCG::do_tr() { _y[0].x = tr_input_limited(); tr_eval(); assert(_y[0].f0 != LINEAR); store_values(); q_load(); _loss0 = _y[0].f0; _m0.x = tr_outvolts(); // fake _m0.c1 = _y[0].f1 * tr_outvolts(); _m0.c0 = -_y[0].x * _m0.c1; return converged(); } /*--------------------------------------------------------------------------*/ void DEV_VCG::do_ac() { if (using_ac_eval()) { ac_eval(); _acg = _ev * _m0.x; _ev *= _y[0].x; }else{ assert(_ev == _y[0].f0); assert(_acg == _m0.c1); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_VCG p3; DISPATCHER::INSTALL d3(&device_dispatcher, "vcg", &p3); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_vcr.cc����������������������������������������������������������������������������������������0000664�0000000�0000000�00000012411�11454012162�0013244�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_vcr.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * voltage controlled resistor. * y.x = volts(control), ev = y.f0 = ohms, y.f1 = ohms/volt * m.x = volts(control), m.c0 = 0, acg = m.c1 = mhos * _loss0 == 1/R. (mhos) */ //testing=script,complete 2006.07.17 #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class DEV_VCR : public ELEMENT { private: explicit DEV_VCR(const DEV_VCR& p) :ELEMENT(p) {} public: explicit DEV_VCR() :ELEMENT() {} private: // override virtual char id_letter()const {itested();return '\0';} std::string value_name()const {itested(); return "r";} std::string dev_type()const {return "vcr";} int max_nodes()const {return 4;} int min_nodes()const {return 4;} int matrix_nodes()const {return 4;} int net_nodes()const {return 4;} bool use_obsolete_callback_parse()const {return true;} CARD* clone()const {return new DEV_VCR(*this);} void precalc_last(); void tr_iwant_matrix() {tr_iwant_matrix_extended();} void tr_begin(); bool do_tr(); void tr_load() {tr_load_shunt(); tr_load_active();} void tr_unload() {untested(); tr_unload_shunt(); tr_unload_active();} double tr_involts()const {untested(); return dn_diff(_n[IN1].v0(), _n[IN2].v0());} double tr_involts_limited()const {return volts_limited(_n[IN1],_n[IN2]);} double tr_amps()const {untested(); return ELEMENT::tr_amps();} void ac_iwant_matrix() {ac_iwant_matrix_extended();} void ac_begin(); void do_ac(); void ac_load() {ac_load_shunt(); ac_load_active();} COMPLEX ac_involts()const {untested();return _n[IN1]->vac()-_n[IN2]->vac();} COMPLEX ac_amps()const {untested(); return ELEMENT::ac_amps();} std::string port_name(int i)const {untested(); assert(i >= 0); assert(i < 4); static std::string names[] = {"p", "n", "ps", "ns"}; return names[i]; } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void DEV_VCR::precalc_last() { ELEMENT::precalc_last(); assert(!is_constant()); set_not_converged(); } /*--------------------------------------------------------------------------*/ void DEV_VCR::tr_begin() { ELEMENT::tr_begin(); _loss1 = _loss0 = 1./OPT::shortckt; _m0.x = 0.; _m0.c1 = 0.; _m0.c0 = 0.; _m1 = _m0; } /*--------------------------------------------------------------------------*/ bool DEV_VCR::do_tr() { _y[0].x = tr_input_limited(); tr_eval(); trace3("vcr", _y[0].x, _y[0].f0, _y[0].f1); assert(_y[0].f0 != LINEAR); if (_y[0].f0 == 0.) { error(bDEBUG, long_label() + ": short circuit\n"); _y[0].f0 = OPT::shortckt; set_converged(conv_check()); }else{ } store_values(); q_load(); _loss0 = 1./_y[0].f0; _m0.x = tr_outvolts(); // fake _m0.c1 = -_y[0].f1 * _loss0 * _loss0 * tr_outvolts(); _m0.c0 = -_y[0].x * _m0.c1; trace3("vcr", _loss0, _m0.c0, _m0.c1); return converged(); } /*--------------------------------------------------------------------------*/ void DEV_VCR::ac_begin() { _ev = _y[0].f0; _acg = _m0.c1; trace4("vcr-ac_begin", _y[0].f0, _y[0].f1, _m0.c0, _m0.c1); trace4("", _ev.real(), _ev.imag(), _acg.real(), _acg.imag()); trace1("", _loss0); } /*--------------------------------------------------------------------------*/ void DEV_VCR::do_ac() { if (using_ac_eval()) { ac_eval(); _acg = -_ev * _loss0 * _loss0 * _m0.x; trace4("vcr-do_ac(eval)", _y[0].f0, _y[0].f1, _m0.c0, _m0.c1); trace4("", _ev.real(), _ev.imag(), _acg.real(), _acg.imag()); _ev *= _y[0].x; trace4("", _ev.real(), _ev.imag(), _loss0, _m0.x); }else{ trace4("vcr-do_ac", _y[0].f0, _y[0].f1, _m0.c0, _m0.c1); trace4("", _ev.real(), _ev.imag(), _acg.real(), _acg.imag()); trace1("", _loss0); assert(_ev == _y[0].f0); assert(_acg == _m0.c1); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_VCR p1; DISPATCHER::INSTALL d1(&device_dispatcher, "vcr", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_vcvs.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000011074�11454012162�0013437�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_vcvs.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * functions for vcvs * temporary kluge: it has resistance */ //testing=script,complete 2006.07.17 #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class DEV_VCVS : public ELEMENT { private: explicit DEV_VCVS(const DEV_VCVS& p) :ELEMENT(p) {} public: explicit DEV_VCVS() :ELEMENT() {} private: // override virtual char id_letter()const {return 'E';} std::string value_name()const {return "gain";} std::string dev_type()const {return "vcvs";} int max_nodes()const {return 4;} int min_nodes()const {return 4;} int matrix_nodes()const {return 4;} int net_nodes()const {return 4;} bool use_obsolete_callback_parse()const {return true;} CARD* clone()const {return new DEV_VCVS(*this);} void precalc_last(); void tr_iwant_matrix() {tr_iwant_matrix_extended();} void tr_begin(); bool do_tr(); void tr_load() {tr_load_shunt(); tr_load_active();} void tr_unload() {untested();tr_unload_active();} double tr_involts()const {return dn_diff(_n[IN1].v0(), _n[IN2].v0());} double tr_involts_limited()const {return volts_limited(_n[IN1],_n[IN2]);} void ac_iwant_matrix() {ac_iwant_matrix_extended();} void ac_begin(); void do_ac(); void ac_load() {ac_load_shunt(); ac_load_active();} COMPLEX ac_involts()const {return _n[IN1]->vac() - _n[IN2]->vac();} std::string port_name(int i)const { assert(i >= 0); assert(i < 4); static std::string names[] = {"p", "n", "ps", "ns"}; return names[i]; } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void DEV_VCVS::precalc_last() { ELEMENT::precalc_last(); set_constant(!has_tr_eval()); set_converged(!has_tr_eval()); } /*--------------------------------------------------------------------------*/ void DEV_VCVS::tr_begin() { ELEMENT::tr_begin(); _loss1 = _loss0 = 1./OPT::shortckt; _m0.x = 0.; _m0.c1 = -_loss0 * _y[0].f1; _m0.c0 = 0.; _m1 = _m0; } /*--------------------------------------------------------------------------*/ bool DEV_VCVS::do_tr() { if (using_tr_eval()) { _y[0].x = _m0.x = tr_involts_limited(); //_y[0].x = tr_input_limited(); //assert(_y[0].x == _m0.x); tr_eval(); assert(_y[0].f0 != LINEAR); store_values(); q_load(); _m0 = CPOLY1(_y[0]); _m0 *= -_loss0; }else{ assert(conchk(_loss0, 1./OPT::shortckt)); assert(_y[0].f0 == LINEAR); assert(_y[0].f1 == value()); assert(conchk(_m0.c1, -_loss0 * _y[0].f1)); assert(_m0.c0 == 0.); assert(_y1 == _y[0]); assert(converged()); } return converged(); } /*--------------------------------------------------------------------------*/ void DEV_VCVS::ac_begin() { _loss1 = _loss0 = 1./OPT::shortckt; _ev = _y[0].f1; _acg = -_loss0 * _ev; } /*--------------------------------------------------------------------------*/ void DEV_VCVS::do_ac() { if (using_ac_eval()) { ac_eval(); _acg = -_loss0 * _ev; }else{ assert(_ev == _y[0].f1); assert(has_tr_eval() || _ev == double(value())); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_VCVS p1; DISPATCHER::INSTALL d1(&device_dispatcher, "E|vcvs", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/d_vs.cc�����������������������������������������������������������������������������������������0000664�0000000�0000000�00000011637�11454012162�0013113�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: d_vs.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * functions for fixed voltage sources * temporary kluge: it has resistance */ //testing=script 2006.07.17 #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class DEV_VS : public ELEMENT { private: explicit DEV_VS(const DEV_VS& p) :ELEMENT(p) {} public: explicit DEV_VS() :ELEMENT() {} private: // override virtual char id_letter()const {return 'V';} std::string value_name()const {return "dc";} std::string dev_type()const {return "vsource";} int max_nodes()const {return 2;} int min_nodes()const {return 2;} int matrix_nodes()const {return 2;} int net_nodes()const {return 2;} bool is_source()const {return true;} bool f_is_value()const {return true;} bool has_iv_probe()const {return true;} bool use_obsolete_callback_parse()const {return true;} CARD* clone()const {return new DEV_VS(*this);} void precalc_last(); void tr_iwant_matrix() {tr_iwant_matrix_passive();} void tr_begin(); bool do_tr(); void tr_load() {tr_load_shunt(); tr_load_source();} void tr_unload() {untested();tr_unload_source();} double tr_involts()const {return 0.;} double tr_involts_limited()const {unreachable(); return 0.;} void ac_iwant_matrix() {ac_iwant_matrix_passive();} void ac_begin() {_loss1 = _loss0 = 1./OPT::shortckt; _acg = _ev = 0.;} void do_ac(); void ac_load() {ac_load_shunt(); ac_load_source();} COMPLEX ac_involts()const {return 0.;} COMPLEX ac_amps()const {return (_acg + ac_outvolts()*_loss0);} std::string port_name(int i)const { assert(i >= 0); assert(i < 2); static std::string names[] = {"p", "n"}; return names[i]; } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void DEV_VS::precalc_last() { ELEMENT::precalc_last(); set_constant(!has_tr_eval()); set_converged(!has_tr_eval()); } /*--------------------------------------------------------------------------*/ void DEV_VS::tr_begin() { ELEMENT::tr_begin(); _y1.f0 = _y[0].f0 = 0.; // override _loss1 = _loss0 = 1./OPT::shortckt; _m0.x = 0.; _m0.c0 = -_loss0 * _y[0].f1; _m0.c1 = 0.; _m1 = _m0; if (!using_tr_eval()) { if (_n[OUT2].m_() == 0) { _sim->set_limit(value()); }else if (_n[OUT1].m_() == 0) {untested(); _sim->set_limit(-value()); }else{untested(); //BUG// don't set limit } }else{ } } /*--------------------------------------------------------------------------*/ bool DEV_VS::do_tr() { assert(_m0.x == 0.); if (using_tr_eval()) { _y[0].x = _sim->_time0; tr_eval(); if (_n[OUT2].m_() == 0) { _sim->set_limit(_y[0].f1); }else if (_n[OUT1].m_() == 0) { _sim->set_limit(-_y[0].f1); }else{ //BUG// don't set limit } store_values(); q_load(); _m0.c0 = -_loss0 * _y[0].f1; assert(_m0.c1 == 0.); }else{itested(); assert(conchk(_loss0, 1./OPT::shortckt)); assert(_y[0].x == 0.); assert(_y[0].f0 == 0.); assert(_y[0].f1 == value()); assert(_m0.x == 0.); assert(conchk(_m0.c0, -_loss0 * _y[0].f1)); assert(_m0.c1 == 0.); assert(_y1 == _y[0]); assert(converged()); } return converged(); } /*--------------------------------------------------------------------------*/ void DEV_VS::do_ac() { if (using_ac_eval()) { ac_eval(); _acg = -_loss0 * _ev; }else{itested(); assert(_acg == 0.); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_VS p1; DISPATCHER::INSTALL d1(&device_dispatcher, "V|vsource", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������src/declare.h���������������������������������������������������������������������������������������0000664�0000000�0000000�00000003154�11454012162�0013414�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: declare.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * global functions * A remnant of the old C code */ //testing=trivial 2006.07.17 #ifndef DECLARE_H #define DECLARE_H #include "md.h" class PROBELIST; /*--------------------------------------------------------------------------*/ /* fft */ INTERFACE void fft(COMPLEX*,int,int); /* generat */ INTERFACE double gen(); /* plot */ void plottr(double,const PROBELIST&); int plopen(double,double,const PROBELIST&); INTERFACE void plclose(); INTERFACE void plclear(); /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/e_aux.h�����������������������������������������������������������������������������������������0000664�0000000�0000000�00000003565�11454012162�0013124�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_aux.h,v 26.83 2008/06/05 04:46:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * helper functions, etc., that sort of belong to circuit elements */ //testing=script 2007.07.13 #ifndef E_AUX_H #define E_AUX_H #include "e_node.h" /*--------------------------------------------------------------------------*/ template T port_impedance(const node_t& n1, const node_t& n2, BSMATRIX& mat, const T& parallel) { T* zapit = new T[mat.size()+2]; for (int ii = 0; ii < mat.size()+2; ++ii) { zapit[ii] = 0.; } if (n1.m_() != 0) { zapit[n1.m_()] = 1.; }else{untested(); } if (n2.m_() != 0) {untested(); zapit[n2.m_()] = -1.; }else{ } mat.fbsub(zapit); T raw_z = zapit[n1.m_()] - zapit[n2.m_()]; delete [] zapit; return (parallel != 0.) ? 1. / ((1./raw_z)-parallel) : raw_z; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif �������������������������������������������������������������������������������������������������������������������������������������������src/e_base.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000011260�11454012162�0013366�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_base.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Base class for "cards" in the circuit description file */ //testing=script 2006.07.12 #include "u_sim_data.h" #include "m_wave.h" #include "u_prblst.h" #include "u_xprobe.h" #include "e_base.h" /*--------------------------------------------------------------------------*/ static char fix_case(char c) { return ((OPT::case_insensitive) ? (static_cast(tolower(c))) : (c)); } /*--------------------------------------------------------------------------*/ double CKT_BASE::tr_probe_num(const std::string&)const {return NOT_VALID;} XPROBE CKT_BASE::ac_probe_ext(const std::string&)const {return XPROBE(NOT_VALID, mtNONE);} /*--------------------------------------------------------------------------*/ SIM_DATA sim_data; SIM_DATA* CKT_BASE::_sim = &sim_data; /*--------------------------------------------------------------------------*/ CKT_BASE::~CKT_BASE() { trace1("~CKT_BASE", _probes); PROBE_LISTS::purge(this); trace1("", _probes); assert(_probes==0); } /*--------------------------------------------------------------------------*/ const std::string CKT_BASE::long_label()const { //incomplete(); std::string buffer(short_label()); //for (const CKT_BASE* brh = owner(); exists(brh); brh = brh->owner()) { // buffer += '.' + brh->short_label(); //} return buffer; } /*--------------------------------------------------------------------------*/ double CKT_BASE::probe_num(const std::string& what)const { double x; if (_sim->analysis_is_ac()) { x = ac_probe_num(what); }else{ x = tr_probe_num(what); } return (std::abs(x)>=1) ? x : floor(x/OPT::floor + .5) * OPT::floor; } /*--------------------------------------------------------------------------*/ double CKT_BASE::ac_probe_num(const std::string& what)const { size_t length = what.length(); mod_t modifier = mtNONE; bool want_db = false; char parameter[BUFLEN+1]; strcpy(parameter, what.c_str()); if (length > 2 && Umatch(¶meter[length-2], "db ")) { want_db = true; length -= 2; } if (length > 1) { // selects modifier based on last letter of parameter switch (fix_case(parameter[length-1])) { case 'm': modifier = mtMAG; length--; break; case 'p': modifier = mtPHASE; length--; break; case 'r': modifier = mtREAL; length--; break; case 'i': modifier = mtIMAG; length--; break; default: modifier = mtNONE; break; } } parameter[length] = '\0'; // chop // "p" is "what" with the modifier chopped off. // Try that first. XPROBE xp = ac_probe_ext(parameter); // If we don't find it, try again with the full string. if (!xp.exists()) { xp = ac_probe_ext(what); if (!xp.exists()) { // Still didn't find anything. Print "??". }else{ untested(); // The second attempt worked. } } return xp(modifier, want_db); } /*--------------------------------------------------------------------------*/ /*static*/ double CKT_BASE::probe(const CKT_BASE *This, const std::string& what) { if (exists(This)) { return This->probe_num(what); }else{ /* return 0 if doesn't exist */ return 0.0; /* happens when optimized models */ } /* don't have all parts */ } /*--------------------------------------------------------------------------*/ /*static*/ WAVE* CKT_BASE::find_wave(const std::string& probe_name) { int ii = 0; for (PROBELIST::const_iterator p = PROBE_LISTS::store[_sim->_mode].begin(); p != PROBE_LISTS::store[_sim->_mode].end(); ++p) { if (wmatch(p->label(), probe_name)) { return &(_sim->_waves[ii]); }else{ } ++ii; } return NULL; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/e_base.h����������������������������������������������������������������������������������������0000664�0000000�0000000�00000006276�11454012162�0013243�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_base.h,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * real base for anything to do with a circuit */ //testing=obsolete #ifndef E_BASE_H #define E_BASE_H #include "md.h" /*--------------------------------------------------------------------------*/ // external class XPROBE; class WAVE; class OMSTREAM; class SIM_DATA; /*--------------------------------------------------------------------------*/ class INTERFACE CKT_BASE { private: mutable int _probes; /* number of probes set */ std::string _label; public: static SIM_DATA* _sim; //-------------------------------------------------------------------- protected: // create and destroy explicit CKT_BASE() :_probes(0), _label() {} explicit CKT_BASE(const std::string& s) :_probes(0), _label(s) {} explicit CKT_BASE(const CKT_BASE& p) :_probes(0), _label(p._label) {} virtual ~CKT_BASE(); //-------------------------------------------------------------------- public: // user stuff virtual void help(CS&, OMSTREAM&)const {untested();} virtual std::string status()const {return "";} //-------------------------------------------------------------------- public: // probes double probe_num(const std::string&)const; double ac_probe_num(const std::string&)const; virtual double tr_probe_num(const std::string&)const; virtual XPROBE ac_probe_ext(const std::string&)const; void inc_probes()const {++_probes;} void dec_probes()const {assert(_probes>0); --_probes;} bool has_probes()const {return _probes > 0;} static double probe(const CKT_BASE*,const std::string&); static WAVE* find_wave(const std::string& probe_name); //-------------------------------------------------------------------- public: // label bool operator!=(const std::string& n)const {return strcasecmp(_label.c_str(),n.c_str())!=0;} virtual const std::string long_label()const; const std::string& short_label()const {return _label;} void set_label(const std::string& s) {_label = s;} }; /*--------------------------------------------------------------------------*/ inline bool exists(const CKT_BASE* c) {return c!=0;} /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/e_card.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000020006�11454012162�0013363�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_card.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Base class for "cards" in the circuit description file */ //testing=script 2006.07.12 #include "u_time_pair.h" #include "e_cardlist.h" #include "e_node.h" #include "e_card.h" /*--------------------------------------------------------------------------*/ const int POOLSIZE = 4; /*--------------------------------------------------------------------------*/ CARD::CARD() :CKT_BASE(), _evaliter(-100), _subckt(0), _owner(0), _constant(false), _n(0), _net_nodes(0) { } /*--------------------------------------------------------------------------*/ CARD::CARD(const CARD& p) :CKT_BASE(p), _evaliter(-100), _subckt(0), //BUG// isn't this supposed to copy???? _owner(0), _constant(p._constant), _n(0), _net_nodes(p._net_nodes) { } /*--------------------------------------------------------------------------*/ CARD::~CARD() { delete _subckt; } /*--------------------------------------------------------------------------*/ const std::string CARD::long_label()const { std::string buffer(short_label()); for (const CARD* brh = owner(); exists(brh); brh = brh->owner()) { buffer = brh->short_label() + '.' + buffer; } return buffer; } /*--------------------------------------------------------------------------*/ /* connects_to: does this part connect to this node? * input: a node * returns: how many times this part connects to it. * does not traverse subcircuits */ int CARD::connects_to(const node_t& node)const { untested(); int count = 0; if (is_device()) { for (int ii = 0; ii < net_nodes(); ++ii) { untested(); if (node.n_() == _n[ii].n_()) { ++count; }else{untested(); } } }else{untested(); } return count; } /*--------------------------------------------------------------------------*/ CARD_LIST* CARD::scope() { if (owner()) { return owner()->subckt(); // normal element, owner determines scope }else{ return &(CARD_LIST::card_list); // root circuit } } /*--------------------------------------------------------------------------*/ const CARD_LIST* CARD::scope()const { if (owner()) { return owner()->subckt(); // normal element, owner determines scope }else{ return &(CARD_LIST::card_list); // root circuit } } /*--------------------------------------------------------------------------*/ /* find_in_my_scope: find in same scope as myself * whatever is found will have the same owner as me. * capable of finding me. * throws exception if can't find. */ CARD* CARD::find_in_my_scope(const std::string& name) { assert(name != ""); assert(scope()); CARD_LIST::iterator i = scope()->find_(name); if (i == scope()->end()) { throw Exception_Cant_Find(long_label(), name, ((owner()) ? owner()->long_label() : "(root)")); }else{ } return *i; } /*--------------------------------------------------------------------------*/ /* find_in_my_scope: find in same scope as myself * whatever is found will have the same owner as me. * capable of finding me. * throws exception if can't find. */ const CARD* CARD::find_in_my_scope(const std::string& name)const { assert(name != ""); assert(scope()); CARD_LIST::const_iterator i = scope()->find_(name); if (i == scope()->end()) { throw Exception_Cant_Find(long_label(), name, ((owner()) ? owner()->long_label() : "(root)")); }else{ } return *i; } /*--------------------------------------------------------------------------*/ /* find_in_parent_scope: find in parent's scope * parent is what my scope is a copy of. * capable of finding my parent, who should be just like me. * If there is no parent (I'm an original), use my scope. * throws exception if can't find. */ const CARD* CARD::find_in_parent_scope(const std::string& name)const { assert(name != ""); const CARD_LIST* p_scope = (scope()->parent()) ? scope()->parent() : scope(); CARD_LIST::const_iterator i = p_scope->find_(name); if (i == p_scope->end()) { throw Exception_Cant_Find(long_label(), name); }else{ } return *i; } /*--------------------------------------------------------------------------*/ /* find_looking_out: find in my or enclosing scope * capable of finding me, or anything back to root. * throws exception if can't find. */ const CARD* CARD::find_looking_out(const std::string& name)const { try { return find_in_parent_scope(name); }catch (Exception_Cant_Find&) { if (owner()) { return owner()->find_looking_out(name); }else if (makes_own_scope()) { // probably a subckt or "module" CARD_LIST::const_iterator i = CARD_LIST::card_list.find_(name); if (i != CARD_LIST::card_list.end()) {itested(); return *i; }else{ throw; } }else{ throw; } } } /*--------------------------------------------------------------------------*/ TIME_PAIR CARD::tr_review() { return TIME_PAIR(NEVER,NEVER); } /*--------------------------------------------------------------------------*/ void CARD::new_subckt() { delete _subckt; _subckt = new CARD_LIST; } /*--------------------------------------------------------------------------*/ void CARD::new_subckt(const CARD* Model, CARD* Owner, const CARD_LIST* Scope, PARAM_LIST* Params) { delete _subckt; _subckt = new CARD_LIST(Model, Owner, Scope, Params); } /*--------------------------------------------------------------------------*/ void CARD::renew_subckt(const CARD* Model, CARD* Owner, const CARD_LIST* Scope, PARAM_LIST* Params) { if (_sim->is_first_expand()) { new_subckt(Model, Owner, Scope, Params); }else{untested(); assert(subckt()); subckt()->attach_params(Params, scope()); } } /*--------------------------------------------------------------------------*/ node_t& CARD::n_(int i)const { return _n[i]; } /*--------------------------------------------------------------------------*/ void CARD::set_param_by_name(std::string Name, std::string Value) { //BUG// ugly linear search for (int i = param_count() - 1; i >= 0; --i) { for (int j = 0; param_name(i,j) != ""; ++j) { // multiple names if (Umatch(Name, param_name(i,j) + ' ')) { set_param_by_index(i, Value, 0/*offset*/); return; //success }else{ //keep looking } } } throw Exception_No_Match(Name); } /*--------------------------------------------------------------------------*/ /* set_dev_type: Attempt to change the type of an existing device. * Usually, it just throws an exception, unless there is no change. * Practical use is to override, so you can set things like NPN vs. PNP. */ void CARD::set_dev_type(const std::string& New_Type) { if (!Umatch(New_Type, dev_type() + ' ')) {itested(); //throw Exception_Cant_Set_Type(dev_type(), New_Type); }else{ // it matches -- ok. } } /*--------------------------------------------------------------------------*/ bool CARD::evaluated()const { if (_evaliter == _sim->iteration_tag()) { return true; }else{ _evaliter = _sim->iteration_tag(); return false; } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/e_card.h����������������������������������������������������������������������������������������0000664�0000000�0000000�00000015134�11454012162�0013233�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_card.h,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * base class for anything in a netlist or circuit file */ //testing=script 2007.07.13 #ifndef E_CARD_H #define E_CARD_H #include "e_base.h" /*--------------------------------------------------------------------------*/ // this file class CARD; /*--------------------------------------------------------------------------*/ // external class node_t; class CARD_LIST; class PARAM_LIST; class LANGUAGE; class TIME_PAIR; /*--------------------------------------------------------------------------*/ class INTERFACE CARD : public CKT_BASE { private: mutable int _evaliter; // model eval iteration number CARD_LIST* _subckt; CARD* _owner; bool _constant; // eval stays the same every iteration protected: node_t* _n; public: int _net_nodes; // actual number of "nodes" in the netlist //-------------------------------------------------------------------- public: // traversal functions CARD* find_in_my_scope(const std::string& name); const CARD* find_in_my_scope(const std::string& name)const; const CARD* find_in_parent_scope(const std::string& name)const; const CARD* find_looking_out(const std::string& name)const; //-------------------------------------------------------------------- protected: // create and destroy. explicit CARD(); explicit CARD(const CARD&); public: virtual ~CARD(); virtual CARD* clone()const {unreachable(); return NULL;} virtual CARD* clone_instance()const {return clone();} //-------------------------------------------------------------------- public: // "elaborate" virtual void precalc_first() {} virtual void expand_first() {} virtual void expand() {} virtual void expand_last() {} virtual void precalc_last() {} virtual void map_nodes() {} //-------------------------------------------------------------------- public: // dc-tran virtual void tr_iwant_matrix() {} virtual void tr_begin() {} virtual void tr_restore() {} virtual void dc_advance() {} virtual void tr_advance() {} virtual void tr_regress() {} virtual bool tr_needs_eval()const {return false;} virtual void tr_queue_eval() {} virtual bool do_tr() {return true;} virtual bool do_tr_last() {return true;} virtual void tr_load() {} virtual TIME_PAIR tr_review(); //{return TIME_PAIR(NEVER,NEVER);} virtual void tr_accept() {} virtual void tr_unload() {untested();} //-------------------------------------------------------------------- public: // ac virtual void ac_iwant_matrix() {} virtual void ac_begin() {} virtual void do_ac() {} virtual void ac_load() {} //-------------------------------------------------------------------- public: // state, aux data virtual char id_letter()const {unreachable(); return '\0';} virtual int net_nodes()const {untested();return 0;} virtual bool is_device()const {return false;} virtual void set_slave() {untested(); assert(!subckt());} bool evaluated()const; void set_constant(bool c) {_constant = c;} bool is_constant()const {return _constant;} //-------------------------------------------------------------------- public: // owner, scope virtual CARD_LIST* scope(); virtual const CARD_LIST* scope()const; virtual bool makes_own_scope()const {return false;} CARD* owner() {return _owner;} const CARD* owner()const {return _owner;} void set_owner(CARD* o) {assert(!_owner||_owner==o); _owner=o;} //-------------------------------------------------------------------- public: // subckt CARD_LIST* subckt() {return _subckt;} const CARD_LIST* subckt()const {return _subckt;} void new_subckt(); void new_subckt(const CARD* model, CARD* owner, const CARD_LIST* scope, PARAM_LIST* p); void renew_subckt(const CARD* model, CARD* owner, const CARD_LIST* scope, PARAM_LIST* p); //-------------------------------------------------------------------- public: // type virtual std::string dev_type()const {unreachable(); return "";} virtual void set_dev_type(const std::string&); //-------------------------------------------------------------------- public: // label -- in CKT_BASE // non-virtual void set_label(const std::string& s) //BASE // non-virtual const std::string& short_label()const //BASE /*virtual*/ const std::string long_label()const; // no further override //-------------------------------------------------------------------- public: // ports -- mostly defer to COMPONENT node_t& n_(int i)const; int connects_to(const node_t& node)const; //-------------------------------------------------------------------- public: // parameters virtual void set_param_by_name(std::string, std::string); virtual void set_param_by_index(int i, std::string&, int offset) {untested(); throw Exception_Too_Many(i, 0, offset);} virtual int param_count_dont_print()const {return 0;} virtual int param_count()const {return 0;} virtual bool param_is_printable(int)const {untested(); return false;} virtual std::string param_name(int)const {return "";} virtual std::string param_name(int i,int j)const {return (j==0) ? param_name(i) : "";} virtual std::string param_value(int)const {untested(); return "";} virtual std::string value_name()const = 0; //-------------------------------------------------------------------- public: // obsolete -- do not use in new code virtual bool use_obsolete_callback_parse()const {return false;} virtual bool use_obsolete_callback_print()const {return false;} virtual void print_args_obsolete_callback(OMSTREAM&,LANGUAGE*)const {unreachable();} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/e_cardlist.cc�����������������������������������������������������������������������������������0000664�0000000�0000000�00000034765�11454012162�0014300�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_cardlist.cc,v 26.136 2009/12/08 02:03:49 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Base class for "cards" in the circuit description file * This file contains functions that process a list of cards */ //testing=script 2006.07.10 #include "u_time_pair.h" #include "e_node.h" #include "u_nodemap.h" #include "e_model.h" /*--------------------------------------------------------------------------*/ #define trace_func_comp() trace0((__func__ + (":" + (**ci).long_label())).c_str()) /*--------------------------------------------------------------------------*/ CARD_LIST::CARD_LIST() :_parent(NULL), _nm(new NODE_MAP), _params(NULL), _language(NULL) { } /*--------------------------------------------------------------------------*/ CARD_LIST::CARD_LIST(const CARD* model, CARD* owner, const CARD_LIST* scope, PARAM_LIST* p) :_parent(NULL), _nm(new NODE_MAP), _params(NULL), _language(NULL) { assert(model); assert(model->subckt()); assert(owner); assert(!p || scope); attach_params(p, scope); shallow_copy(model->subckt()); set_owner(owner); map_subckt_nodes(model, owner); } /*--------------------------------------------------------------------------*/ CARD_LIST::~CARD_LIST() { erase_all(); delete _nm; if (!_parent) { delete _params; }else{ } } /*--------------------------------------------------------------------------*/ PARAM_LIST* CARD_LIST::params() { if (!_params) { assert(!_parent); _params = new PARAM_LIST; }else{ } return _params; } /*--------------------------------------------------------------------------*/ PARAM_LIST* CARD_LIST::params()const { if (_params) { return _params; }else{ //BUG//const static PARAM_LIST empty_params; return &empty_params; } } /*--------------------------------------------------------------------------*/ CARD_LIST::iterator CARD_LIST::find_again(const std::string& short_name, CARD_LIST::iterator Begin) { return notstd::find_ptr(Begin, end(), short_name); } /*--------------------------------------------------------------------------*/ CARD_LIST::const_iterator CARD_LIST::find_again(const std::string& short_name, CARD_LIST::const_iterator Begin)const { return notstd::find_ptr(Begin, end(), short_name); } /*--------------------------------------------------------------------------*/ CARD_LIST& CARD_LIST::erase(iterator ci) { assert(ci != end()); delete *ci; _cl.erase(ci); return *this; } /*--------------------------------------------------------------------------*/ CARD_LIST& CARD_LIST::erase(CARD* c) { delete c; _cl.remove(c); return *this; } /*--------------------------------------------------------------------------*/ /* erase_all: empty the list, destroy contents * Beware: something else may be pointing to them, leaving dangling ptr. */ CARD_LIST& CARD_LIST::erase_all() { while (!_cl.empty()) { delete _cl.back(); _cl.pop_back(); } return *this; } /*--------------------------------------------------------------------------*/ CARD_LIST& CARD_LIST::set_owner(CARD* owner) { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).set_owner(owner); } return *this; } /*--------------------------------------------------------------------------*/ /* set_slave: set a whole circuit to "slave" mode. * Only useful for subckts. */ CARD_LIST& CARD_LIST::set_slave() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).set_slave(); } return *this; } /*--------------------------------------------------------------------------*/ /* expand: expand (flatten) a list of components (subckts) * Scan component list. Expand each subckt: create actual elements * for flat representation to use for simulation. */ CARD_LIST& CARD_LIST::expand() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).precalc_first(); } for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).expand_first(); } for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).expand(); } for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).expand_last(); } return *this; } /*--------------------------------------------------------------------------*/ CARD_LIST& CARD_LIST::precalc_first() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).precalc_first(); } return *this; } /*--------------------------------------------------------------------------*/ CARD_LIST& CARD_LIST::precalc_last() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).precalc_last(); } return *this; } /*--------------------------------------------------------------------------*/ /* map_nodes: create mapping between user node names and internal numbers */ CARD_LIST& CARD_LIST::map_nodes() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).map_nodes(); } return *this; } /*--------------------------------------------------------------------------*/ /* tr_iwant_matrix: allocate solution matrix * also sets some flags for mixed-mode */ CARD_LIST& CARD_LIST::tr_iwant_matrix() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).tr_iwant_matrix(); } return *this; } /*--------------------------------------------------------------------------*/ /* tr_begin: first pass on a new transient simulation (initial DC) */ CARD_LIST& CARD_LIST::tr_begin() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).tr_begin(); } return *this; } /*--------------------------------------------------------------------------*/ /* tr_restore: first pass on restarting a transient simulation */ CARD_LIST& CARD_LIST::tr_restore() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).tr_restore(); } return *this; } /*--------------------------------------------------------------------------*/ /* dc_advance: first pass on a new step in a dc sweep */ CARD_LIST& CARD_LIST::dc_advance() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).dc_advance(); } return *this; } /*--------------------------------------------------------------------------*/ /* tr_advance: first pass on a new time step */ CARD_LIST& CARD_LIST::tr_advance() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).tr_advance(); } return *this; } /*--------------------------------------------------------------------------*/ /* tr_regress: throw away the last result and try again, first pass on redo */ CARD_LIST& CARD_LIST::tr_regress() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).tr_regress(); } return *this; } /*--------------------------------------------------------------------------*/ /* tr_needs_eval: determine if anything needs to be evaluated */ bool CARD_LIST::tr_needs_eval()const { for (const_iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); if ((**ci).tr_needs_eval()) { return true; }else{itested(); } } untested(); return false; } /*--------------------------------------------------------------------------*/ /* tr_queue_eval: build evaluator queue */ CARD_LIST& CARD_LIST::tr_queue_eval() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).tr_queue_eval(); } return *this; } /*--------------------------------------------------------------------------*/ /* tr_eval: evaluate a list of models * evaluates a list (or sublist), checks convergence, etc. * does not load the matrix * argument is the head of the netlist. * recursively called to evaluate subcircuits */ bool CARD_LIST::do_tr() { bool isconverged = true; if (OPT::bypass) { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); if ((**ci).tr_needs_eval()) { isconverged &= (**ci).do_tr(); }else{ } } }else{ for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); isconverged &= (**ci).do_tr(); } } return isconverged; } /*--------------------------------------------------------------------------*/ /* tr_load: load list of models to the matrix * recursively called to load subcircuits * Called only when either !OPT::traceload or !SIM::inc_mode */ CARD_LIST& CARD_LIST::tr_load() { if (CKT_BASE::_sim->is_inc_mode()) {itested(); assert(!OPT::traceload); for (iterator ci=begin(); ci!=end(); ++ci) {itested(); trace_func_comp(); CARD* brh = *ci; if (!brh->is_constant()) {itested(); brh->tr_load(); }else{itested(); } } }else{ for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); CARD* brh = *ci; brh->tr_load(); } } return *this; } /*--------------------------------------------------------------------------*/ TIME_PAIR CARD_LIST::tr_review() { TIME_PAIR time_by; for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); time_by.min((**ci).tr_review()); } return time_by; } /*--------------------------------------------------------------------------*/ /* tr_accept: final acceptance of a time step, before moving on */ CARD_LIST& CARD_LIST::tr_accept() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).tr_accept(); } return *this; } /*--------------------------------------------------------------------------*/ /* tr_unload: remove a list of models from the matrix * recursively called to unload subcircuits */ CARD_LIST& CARD_LIST::tr_unload() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).tr_unload(); } return *this; } /*--------------------------------------------------------------------------*/ /* ac_iwant_matrix: allocate solution matrix */ CARD_LIST& CARD_LIST::ac_iwant_matrix() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).ac_iwant_matrix(); } return *this; } /*--------------------------------------------------------------------------*/ /* ac_begin: first pass on a new ac simulation */ CARD_LIST& CARD_LIST::ac_begin() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).ac_begin(); } return *this; } /*--------------------------------------------------------------------------*/ CARD_LIST& CARD_LIST::do_ac() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); if (!(**ci).evaluated()) { (**ci).do_ac(); }else{ } } return *this; } /*--------------------------------------------------------------------------*/ /* ac_load: load list of models to the matrix * recursively called to load subcircuits */ CARD_LIST& CARD_LIST::ac_load() { for (iterator ci=begin(); ci!=end(); ++ci) { trace_func_comp(); (**ci).ac_load(); } return *this; } /*--------------------------------------------------------------------------*/ void CARD_LIST::attach_params(PARAM_LIST* p, const CARD_LIST* scope) { if (p) { assert(scope); if (_params) { delete _params; _params = NULL; }else{ } _params = new PARAM_LIST; _params->eval_copy(*p, scope); }else{ } } /*--------------------------------------------------------------------------*/ void CARD_LIST::shallow_copy(const CARD_LIST* p) { assert(p); _parent = p; for (const_iterator ci = p->begin(); ci != p->end(); ++ci) { trace_func_comp(); if ((**ci).is_device() || dynamic_cast(*ci)) { CARD* copy = (**ci).clone(); push_back(copy); }else{ } } } /*--------------------------------------------------------------------------*/ // set up the map of external to expanded node numbers void CARD_LIST::map_subckt_nodes(const CARD* model, const CARD* owner) { assert(model); assert(model->subckt()); assert(model->subckt()->nodes()); assert(owner); //assert(owner->subckt()); //assert(owner->subckt() == this); trace0(model->long_label().c_str()); trace0(owner->long_label().c_str()); int num_nodes_in_subckt = model->subckt()->nodes()->how_many(); int* map = new int[num_nodes_in_subckt+1]; { map[0] = 0; // self test: verify that port node numbering is correct for (int port = 0; port < model->net_nodes(); ++port) { assert(model->n_(port).e_() <= num_nodes_in_subckt); //assert(model->n_(port).e_() == port+1); trace3("ports", port, model->n_(port).e_(), owner->n_(port).t_()); } { // take care of the "port" nodes (external connections) // map them to what the calling circuit wants int i=0; for (i=1; i <= model->net_nodes(); ++i) { map[i] = owner->n_(i-1).t_(); trace3("ports", i, map[i], owner->n_(i-1).t_()); } // get new node numbers, and assign them to the remaining for (assert(i==model->net_nodes() + 1); i <= num_nodes_in_subckt; ++i) { // for each remaining node in card_list map[i] = CKT_BASE::_sim->newnode_subckt(); trace2("internal", i, map[i]); } } } // "map" now contains a translation list, // from subckt local numbers to matrix index numbers // The node list (_nm) in an instance of a subckt does not exist. // Device nodes (type node_t) points to the NODE in the parent. // Mapping is done in node_t. // scan the list, map the nodes for (CARD_LIST::iterator ci = begin(); ci != end(); ++ci) { // for each card in card_list if ((**ci).is_device()) { for (int ii = 0; ii < (**ci).net_nodes(); ++ii) { // for each connection node in card (**ci).n_(ii).map_subckt_node(map, owner); } }else{ assert(dynamic_cast(*ci)); } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������src/e_cardlist.h������������������������������������������������������������������������������������0000664�0000000�0000000�00000013177�11454012162�0014134�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_cardlist.h,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * "card" container -- list of circuit elements */ //testing=script,complete 2006.07.11 #ifndef E_CARDLIST_H #define E_CARDLIST_H #include "md.h" /*--------------------------------------------------------------------------*/ // defined here class CARD_LIST; /*--------------------------------------------------------------------------*/ // external class CARD; class PARAM_LIST; class NODE_MAP; class LANGUAGE; class TIME_PAIR; /*--------------------------------------------------------------------------*/ class INTERFACE CARD_LIST { private: const CARD_LIST* _parent; mutable NODE_MAP* _nm; mutable PARAM_LIST* _params; LANGUAGE* _language; std::list _cl; public: // internal types typedef std::list::iterator iterator; typedef std::list::const_iterator const_iterator; class fat_iterator { private: CARD_LIST* _list; iterator _iter; private: explicit fat_iterator() {unreachable();} public: fat_iterator(const fat_iterator& p) : _list(p._list), _iter(p._iter) {} explicit fat_iterator(CARD_LIST* l, iterator i) : _list(l), _iter(i) {} bool is_end()const {return _iter == _list->end();} CARD* operator*() {return (is_end()) ? NULL : *_iter;} fat_iterator& operator++() {assert(!is_end()); ++_iter; return *this;} fat_iterator operator++(int) {assert(!is_end()); fat_iterator t(*this); ++_iter; return t;} bool operator==(const fat_iterator& x)const {unreachable(); assert(_list==x._list); return (_iter==x._iter);} bool operator!=(const fat_iterator& x)const {assert(_list==x._list); return (_iter!=x._iter);} iterator iter()const {return _iter;} CARD_LIST* list()const {return _list;} fat_iterator end()const {return fat_iterator(_list, _list->end());} void insert(CARD* c) {list()->insert(iter(),c);} }; // status queries bool is_empty()const {return _cl.empty();} const CARD_LIST* parent()const {return _parent;} const LANGUAGE* language()const {untested(); return _language;} // return an iterator iterator begin() {return _cl.begin();} iterator end() {return _cl.end();} iterator find_again(const std::string& short_name, iterator); iterator find_(const std::string& short_name) {return find_again(short_name, begin());} // return a const_iterator const_iterator begin()const {return _cl.begin();} const_iterator end()const {return _cl.end();} const_iterator find_again(const std::string& short_name, const_iterator)const; const_iterator find_(const std::string& short_name)const {return find_again(short_name, begin());} // add to it CARD_LIST& push_front(CARD* c) {_cl.push_front(c); return *this;} CARD_LIST& push_back(CARD* c) {_cl.push_back(c); return *this;} CARD_LIST& insert(CARD_LIST::iterator i, CARD* c) {_cl.insert(i, c); return *this;} // take things out CARD_LIST& erase(iterator i); CARD_LIST& erase(CARD* c); CARD_LIST& erase_all(); // operations on the whole list CARD_LIST& set_owner(CARD* owner); CARD_LIST& set_slave(); CARD_LIST& precalc_first(); CARD_LIST& expand(); CARD_LIST& precalc_last(); CARD_LIST& map_nodes(); CARD_LIST& tr_iwant_matrix(); CARD_LIST& tr_begin(); CARD_LIST& tr_restore(); CARD_LIST& dc_advance(); CARD_LIST& tr_advance(); CARD_LIST& tr_regress(); bool tr_needs_eval()const; CARD_LIST& tr_queue_eval(); bool do_tr(); CARD_LIST& tr_load(); TIME_PAIR tr_review(); CARD_LIST& tr_accept(); CARD_LIST& tr_unload(); CARD_LIST& ac_iwant_matrix(); CARD_LIST& ac_begin(); CARD_LIST& do_ac(); CARD_LIST& ac_load(); NODE_MAP* nodes()const {assert(_nm); return _nm;} PARAM_LIST* params(); PARAM_LIST* params()const; // more complex stuff void attach_params(PARAM_LIST* p, const CARD_LIST* scope); void shallow_copy(const CARD_LIST*); void map_subckt_nodes(const CARD* model, const CARD* owner); explicit CARD_LIST(); CARD_LIST(const CARD* model, CARD* owner, const CARD_LIST* scope, PARAM_LIST* p); ~CARD_LIST(); private: explicit CARD_LIST(const CARD_LIST&) {unreachable(); incomplete();} public: static CARD_LIST card_list; // in globals.cc }; /*--------------------------------------------------------------------------*/ INTERFACE CARD_LIST::fat_iterator findbranch(CS&,CARD_LIST::fat_iterator); /*--------------------------------------------------------------------------*/ inline CARD_LIST::fat_iterator findbranch(CS& cmd, CARD_LIST* cl) { assert(cl); return findbranch(cmd, CARD_LIST::fat_iterator(cl, cl->begin())); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/e_ccsrc.cc��������������������������������������������������������������������������������������0000664�0000000�0000000�00000005766�11454012162�0013567�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_ccsrc.cc,v 26.124 2009/09/28 22:59:33 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * current controlled source base */ //testing=script,complete 2006.07.12 #include "e_ccsrc.h" /*--------------------------------------------------------------------------*/ void CCSRC_BASE::expand_last() { ELEMENT::expand_last(); if (_input_label != "") { _input = dynamic_cast(find_in_my_scope(_input_label)); }else{untested(); // _input already set, an internal element. example: mutual L. } if (!_input) {untested(); throw Exception(long_label() + ": " + _input_label + " cannot be used as current probe"); }else if (_input->subckt()) {untested(); throw Exception(long_label() + ": " + _input_label + " has a subckt, cannot be used as current probe"); }else if (_input->has_inode()) {untested(); _n[IN1] = _input->n_(IN1); _n[IN2].set_to_ground(this); }else if (_input->has_iv_probe()) { _n[IN1] = _input->n_(OUT1); _n[IN2] = _input->n_(OUT2); }else{ throw Exception(long_label() + ": " + _input_label + " cannot be used as current probe"); } } /*--------------------------------------------------------------------------*/ void CCSRC_BASE::set_port_by_index(int num, std::string& Value) { if (num == 2) { _input_label = Value; }else{ ELEMENT::set_port_by_index(num, Value); } } /*--------------------------------------------------------------------------*/ bool CCSRC_BASE::node_is_connected(int i)const { if (i == 2) { return _input_label != ""; }else{ return ELEMENT::node_is_connected(i); } } /*--------------------------------------------------------------------------*/ void CCSRC_BASE::set_parameters_cc(const std::string& Label, CARD *Owner, COMMON_COMPONENT *Common, double Value, const node_t& N0, const node_t& N1, ELEMENT* Input) { node_t nodes[] = {N0, N1}; COMPONENT::set_parameters(Label, Owner, Common, Value, 0, 0, 2, nodes); _input = Input; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ����������src/e_ccsrc.h���������������������������������������������������������������������������������������0000664�0000000�0000000�00000005662�11454012162�0013424�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_ccsrc.h,v 26.126 2009/10/16 05:29:28 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * current controlled source base */ //testing=script 2007.07.13 #ifndef E_CCSRC_H #define E_CCSRC_H #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ class INTERFACE CCSRC_BASE : public ELEMENT { private: protected: explicit CCSRC_BASE() :ELEMENT(), _input_label(), _input(0) {} explicit CCSRC_BASE(const CCSRC_BASE& p) :ELEMENT(p), _input_label(p._input_label), _input(p._input) {} ~CCSRC_BASE() {} protected: // override virtual int max_nodes()const {return 3;} int ext_nodes()const {return 4;} int min_nodes()const {return 3;} int matrix_nodes()const {return 4;} int net_nodes()const {return 2;} int num_current_ports()const {return 1;} const std::string current_port_value(int)const {return _input_label;}; //void precalc_first(); //ELEMENT void expand_last(); //void precalc_last(); //ELEMENT bool tr_needs_eval()const {assert(!is_q_for_eval()); return true;} //void tr_queue_eval() //ELEMENT void tr_unload() {untested(); tr_unload_active();} double tr_involts()const {untested();return dn_diff(_n[IN1].v0(), _n[IN2].v0());} double tr_input()const {untested(); return _input->tr_amps();} double tr_involts_limited()const {return volts_limited(_n[IN1],_n[IN2]);} double tr_input_limited()const {return _input->tr_amps();} COMPLEX ac_involts()const {untested();return _n[IN1]->vac()-_n[IN2]->vac();} void set_port_by_index(int index, std::string& value); bool node_is_connected(int i)const; public: void set_parameters_cc(const std::string& Label, CARD* Parent, COMMON_COMPONENT* Common, double Value, const node_t& N0, const node_t& N1, ELEMENT* Input); public: //BUG// for language plugin std::string _input_label; const ELEMENT* _input; }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ������������������������������������������������������������������������������src/e_compon.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000063770�11454012162�0013764�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_compon.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Base class for elements of a circuit */ //testing=script,noswitch 2009.07.13 #include "u_lang.h" #include "e_model.h" #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ COMMON_COMPONENT::COMMON_COMPONENT(const COMMON_COMPONENT& p) :_tnom_c(p._tnom_c), _dtemp(p._dtemp), _temp_c(p._temp_c), _mfactor(p._mfactor), _value(p._value), _modelname(p._modelname), _model(p._model), _attach_count(0) { } /*--------------------------------------------------------------------------*/ COMMON_COMPONENT::COMMON_COMPONENT(int c) :_tnom_c(NOT_INPUT), _dtemp(0), _temp_c(NOT_INPUT), _mfactor(1), _value(0), _modelname(), _model(0), _attach_count(c) { } /*--------------------------------------------------------------------------*/ COMMON_COMPONENT::~COMMON_COMPONENT() { trace1("common,destruct", _attach_count); assert(_attach_count == 0 || _attach_count == CC_STATIC); } /*--------------------------------------------------------------------------*/ void COMMON_COMPONENT::attach_common(COMMON_COMPONENT*c, COMMON_COMPONENT**to) { assert(to); if (c == *to) { // The new and old are the same object. Do nothing. }else if (!c) {untested(); // There is no new common. probably a simple element detach_common(to); }else if (!*to) { // No old one, but have a new one. ++(c->_attach_count); trace1("++1", c->_attach_count); *to = c; }else if (*c != **to) { // They are different, usually by edit. detach_common(to); ++(c->_attach_count); trace1("++2", c->_attach_count); *to = c; }else if (c->_attach_count == 0) { // The new and old are identical. // Use the old one. // The new one is not used anywhere, so throw it away. trace1("delete", c->_attach_count); delete c; }else{untested(); // The new and old are identical. // Use the old one. // The new one is also used somewhere else, so keep it. } } /*--------------------------------------------------------------------------*/ void COMMON_COMPONENT::detach_common(COMMON_COMPONENT** from) { assert(from); if (*from) { assert((**from)._attach_count > 0); --((**from)._attach_count); trace1("--", (**from)._attach_count); if ((**from)._attach_count == 0) { trace1("delete", (**from)._attach_count); delete *from; }else{ trace1("nodelete", (**from)._attach_count); } *from = NULL; }else{ } } /*--------------------------------------------------------------------------*/ void COMMON_COMPONENT::attach_model(const COMPONENT* d)const { assert(d); _model = d->find_model(modelname()); assert(_model); } /*--------------------------------------------------------------------------*/ void COMMON_COMPONENT::parse_modelname(CS& cmd) { set_modelname(cmd.ctos(TOKENTERM)); } /*--------------------------------------------------------------------------*/ // called only by COMMON_COMPONENT::parse_obsolete bool COMMON_COMPONENT::parse_param_list(CS& cmd) { unsigned start = cmd.cursor(); unsigned here = cmd.cursor(); do{ parse_params_obsolete_callback(cmd); //BUG//callback }while (cmd.more() && !cmd.stuck(&here)); return cmd.gotit(start); } /*--------------------------------------------------------------------------*/ void COMMON_COMPONENT::parse_common_obsolete_callback(CS& cmd) //used { if (cmd.skip1b('(')) { // start with a paren unsigned start = cmd.cursor(); parse_param_list(cmd); if (cmd.gotit(start)) { // ( params ( .... // named args before num list if (cmd.skip1b('(')) { // ( params ( list ) params ) parse_numlist(cmd); if (!cmd.skip1b(')')) {untested(); cmd.warn(bWARNING, "need )"); }else{ } }else{ // ( params list params ) parse_numlist(cmd); //BUG// } parse_param_list(cmd); if (!cmd.skip1b(')')) {untested(); cmd.warn(bWARNING, "need )"); }else{ } }else{ // no named args before num list // but there's a paren // not sure whether it belongs to all args or to num list if (cmd.skip1b('(')) { // ( ( list ) params ) // two parens parse_numlist(cmd); if (!cmd.skip1b(')')) {untested(); cmd.warn(bWARNING, "need )"); }else{ } parse_param_list(cmd); if (!cmd.skip1b(')')) {untested(); cmd.warn(bWARNING, "need )"); }else{ } }else{ // ( list ... // only one paren parse_numlist(cmd); if (cmd.skip1b(')')) { // ( list ) params // assume it belongs to num list // and named params follow parse_param_list(cmd); }else{ // ( list params ) // assume it belongs to all args parse_param_list(cmd); if (!cmd.skip1b(')')) { cmd.warn(bWARNING, "need )"); }else{ } } } } }else{ // does not start with a paren unsigned start = cmd.cursor(); parse_param_list(cmd); if (cmd.gotit(start)) { if (cmd.skip1b('(')) { // params ( list ) params parse_numlist(cmd); if (!cmd.skip1b(')')) {untested(); cmd.warn(bWARNING, "need )"); }else{ } }else if (!(cmd.is_alpha())) { // params list params parse_numlist(cmd); }else{ // params (only) } }else{ // list params assert(!(cmd.skip1b('('))); parse_numlist(cmd); } parse_param_list(cmd); if (cmd.skip1b(')')) { cmd.warn(bWARNING, start, "need ("); }else{ } } } /*--------------------------------------------------------------------------*/ void COMMON_COMPONENT::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); print_pair(o, lang, "tnom", _tnom_c, _tnom_c.has_hard_value()); print_pair(o, lang, "dtemp",_dtemp, _dtemp.has_hard_value()); print_pair(o, lang, "temp", _temp_c, _temp_c.has_hard_value()); print_pair(o, lang, "m", _mfactor, _mfactor.has_hard_value()); } /*--------------------------------------------------------------------------*/ void COMMON_COMPONENT::set_param_by_index(int i, std::string& Value, int Offset) { switch (i) { case 0: _tnom_c = Value; break; case 1: _dtemp = Value; break; case 2: _temp_c = Value; break; case 3: _mfactor = Value; break; default: throw Exception_Too_Many(i, 3, Offset); break; } } /*--------------------------------------------------------------------------*/ bool COMMON_COMPONENT::param_is_printable(int i)const { switch (i) { case 0: return _tnom_c.has_hard_value(); case 1: return _dtemp.has_hard_value(); case 2: return _temp_c.has_hard_value(); case 3: return _mfactor.has_hard_value(); default: return false; } } /*--------------------------------------------------------------------------*/ std::string COMMON_COMPONENT::param_name(int i)const { switch (i) { case 0: return "tnom"; case 1: return "dtemp"; case 2: return "temp"; case 3: return "m"; default: return ""; } } /*--------------------------------------------------------------------------*/ std::string COMMON_COMPONENT::param_name(int i, int j)const { return (j==0) ? param_name(i) : ""; } /*--------------------------------------------------------------------------*/ std::string COMMON_COMPONENT::param_value(int i)const { switch (i) { case 0: return _tnom_c.string(); case 1: return _dtemp.string(); case 2: return _temp_c.string(); case 3: return _mfactor.string(); default: return ""; } } /*--------------------------------------------------------------------------*/ void COMMON_COMPONENT::precalc_first(const CARD_LIST* Scope) { assert(Scope); _tnom_c.e_val(OPT::tnom_c, Scope); _dtemp.e_val(0., Scope); _temp_c.e_val(CKT_BASE::_sim->_temp_c + _dtemp, Scope); _mfactor.e_val(1, Scope); _value.e_val(0, Scope); } /*--------------------------------------------------------------------------*/ void COMMON_COMPONENT::tr_eval(ELEMENT*x)const {untested(); assert(_model); _model->tr_eval(x); } /*--------------------------------------------------------------------------*/ void COMMON_COMPONENT::ac_eval(ELEMENT*x)const {untested(); assert(_model); _model->ac_eval(x); } /*--------------------------------------------------------------------------*/ bool COMMON_COMPONENT::operator==(const COMMON_COMPONENT& x)const { return (_modelname == x._modelname && _model == x._model && _tnom_c == x._tnom_c && _dtemp == x._dtemp && _temp_c == x._temp_c && _mfactor == x._mfactor && _value == x._value); } /*--------------------------------------------------------------------------*/ void COMMON_COMPONENT::set_param_by_name(std::string Name, std::string Value) { if (has_parse_params_obsolete_callback()) {untested(); std::string args(Name + "=" + Value); CS cmd(CS::_STRING, args); //obsolete_callback bool ok = parse_params_obsolete_callback(cmd); //BUG//callback if (!ok) {untested(); throw Exception_No_Match(Name); }else{untested(); } }else{ //BUG// ugly linear search for (int i = param_count() - 1; i >= 0; --i) { for (int j = 0; param_name(i,j) != ""; ++j) { if (Umatch(Name, param_name(i,j) + ' ')) { set_param_by_index(i, Value, 0/*offset*/); return; //success }else{ //keep looking } } } itested(); throw Exception_No_Match(Name); } } /*--------------------------------------------------------------------------*/ //BUG// This is a kluge for the spice_wrapper, to disable virtual functions. // It is called during expansion only. void COMMON_COMPONENT::Set_param_by_name(std::string Name, std::string Value) { assert(!has_parse_params_obsolete_callback()); //BUG// ugly linear search for (int i = COMMON_COMPONENT::param_count() - 1; i >= 0; --i) { for (int j = 0; COMMON_COMPONENT::param_name(i,j) != ""; ++j) { if (Umatch(Name, COMMON_COMPONENT::param_name(i,j) + ' ')) { COMMON_COMPONENT::set_param_by_index(i, Value, 0/*offset*/); return; //success }else{ //keep looking } } } throw Exception_No_Match(Name); } /*--------------------------------------------------------------------------*/ bool COMMON_COMPONENT::parse_numlist(CS&) { return false; } /*--------------------------------------------------------------------------*/ bool COMMON_COMPONENT::parse_params_obsolete_callback(CS& cmd) { return ONE_OF || Get(cmd, "tnom", &_tnom_c) || Get(cmd, "dtemp", &_dtemp) || Get(cmd, "temp", &_temp_c) || Get(cmd, "m", &_mfactor) || Get(cmd, "mfactor",&_mfactor) ; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ COMPONENT::COMPONENT() :CARD(), _common(0), _value(0), _mfactor(1), _mfactor_fixed(NOT_VALID), _converged(false), _q_for_eval(-1), _time_by() { _sim->uninit(); } /*--------------------------------------------------------------------------*/ COMPONENT::COMPONENT(const COMPONENT& p) :CARD(p), _common(0), _value(p._value), _mfactor(p._mfactor), _mfactor_fixed(p._mfactor_fixed), _converged(p._converged), _q_for_eval(-1), _time_by(p._time_by) { _sim->uninit(); attach_common(p._common); assert(_common == p._common); } /*--------------------------------------------------------------------------*/ COMPONENT::~COMPONENT() { detach_common(); _sim->uninit(); } /*--------------------------------------------------------------------------*/ bool COMPONENT::node_is_grounded(int i)const { assert(_n); assert(i >= 0); assert(i < net_nodes()); return _n[i].is_grounded(); } /*--------------------------------------------------------------------------*/ bool COMPONENT::node_is_connected(int i)const { assert(_n); assert(i >= 0); assert(i < net_nodes()); return _n[i].is_connected(); } /*--------------------------------------------------------------------------*/ void COMPONENT::set_port_by_name(std::string& int_name, std::string& ext_name) {itested(); for (int i=0; i _net_nodes) { // make the list bigger _net_nodes = num+1; }else{itested(); // it's already big enough, probably assigning out of order } }else{untested(); throw Exception_Too_Many(num, max_nodes(), 0/*offset*/); } } /*--------------------------------------------------------------------------*/ void COMPONENT::set_port_to_ground(int num) {untested(); if (num <= max_nodes()) {untested(); _n[num].set_to_ground(this); if (num+1 > _net_nodes) {untested(); _net_nodes = num+1; }else{untested(); } }else{untested(); throw Exception_Too_Many(num, max_nodes(), 0/*offset*/); } } /*--------------------------------------------------------------------------*/ void COMPONENT::set_dev_type(const std::string& new_type) { if (common()) { if (new_type != dev_type()) { COMMON_COMPONENT* c = common()->clone(); assert(c); c->set_modelname(new_type); attach_common(c); }else{ } }else{ CARD::set_dev_type(new_type); } } /*--------------------------------------------------------------------------*/ void COMPONENT::print_args_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const { assert(lang); assert(has_common()); common()->print_common_obsolete_callback(o, lang); } /*--------------------------------------------------------------------------*/ void COMPONENT::deflate_common() {untested(); unreachable(); if (has_common()) {untested(); COMMON_COMPONENT* deflated_common = mutable_common()->deflate(); if (deflated_common != common()) {untested(); attach_common(deflated_common); }else{untested(); } }else{untested(); unreachable(); } } /*--------------------------------------------------------------------------*/ void COMPONENT::expand() { CARD::expand(); if (has_common()) { COMMON_COMPONENT* new_common = common()->clone(); new_common->expand(this); COMMON_COMPONENT* deflated_common = new_common->deflate(); if (deflated_common != common()) { attach_common(deflated_common); }else{untested(); } }else{ } } /*--------------------------------------------------------------------------*/ void COMPONENT::precalc_first() { CARD::precalc_first(); if (has_common()) { try { mutable_common()->precalc_first(scope()); }catch (Exception_Precalc& e) { error(bWARNING, long_label() + ": " + e.message()); } _mfactor = common()->mfactor(); }else{ } _mfactor.e_val(1, scope()); _value.e_val(0.,scope()); trace1(long_label().c_str(), double(_mfactor)); if (const COMPONENT* o = prechecked_cast(owner())) { _mfactor_fixed = o->mfactor() * _mfactor; }else{ _mfactor_fixed = _mfactor; } trace1(long_label().c_str(), _mfactor_fixed); } /*--------------------------------------------------------------------------*/ void COMPONENT::precalc_last() { CARD::precalc_last(); if (has_common()) { try { mutable_common()->precalc_last(scope()); }catch (Exception_Precalc& e) { error(bWARNING, long_label() + ": " + e.message()); } }else{ } } /*--------------------------------------------------------------------------*/ void COMPONENT::map_nodes() { assert(is_device()); assert(0 <= min_nodes()); //assert(min_nodes() <= net_nodes()); assert(net_nodes() <= max_nodes()); //assert(ext_nodes() + int_nodes() == matrix_nodes()); for (int ii = 0; ii < ext_nodes()+int_nodes(); ++ii) { _n[ii].map(); } if (subckt()) { subckt()->map_nodes(); }else{ } } /*--------------------------------------------------------------------------*/ void COMPONENT::tr_iwant_matrix() { if (is_device()) { assert(matrix_nodes() == 0); if (subckt()) { subckt()->tr_iwant_matrix(); }else{untested(); } }else{ } } /*--------------------------------------------------------------------------*/ void COMPONENT::ac_iwant_matrix() { if (is_device()) { assert(matrix_nodes() == 0); if (subckt()) { subckt()->ac_iwant_matrix(); }else{untested(); } }else{ } } /*--------------------------------------------------------------------------*/ /* set: set parameters, used in model building */ void COMPONENT::set_parameters(const std::string& Label, CARD *Owner, COMMON_COMPONENT *Common, double Value, int , double [], int node_count, const node_t Nodes[]) { set_label(Label); set_owner(Owner); set_value(Value); attach_common(Common); assert(node_count <= net_nodes()); notstd::copy_n(Nodes, node_count, _n); } /*--------------------------------------------------------------------------*/ /* set_slave: force evaluation whenever the owner is evaluated. */ void COMPONENT::set_slave() { mark_always_q_for_eval(); if (subckt()) { subckt()->set_slave(); }else{ } } /*--------------------------------------------------------------------------*/ void COMPONENT::set_value(double v, COMMON_COMPONENT* c) { if (c != _common) { detach_common(); attach_common(c); }else{ } set_value(v); } /*--------------------------------------------------------------------------*/ void COMPONENT::set_param_by_name(std::string Name, std::string Value) { if (has_common()) { COMMON_COMPONENT* c = common()->clone(); assert(c); c->set_param_by_name(Name, Value); attach_common(c); }else{ CARD::set_param_by_name(Name, Value); } } /*--------------------------------------------------------------------------*/ void COMPONENT::set_param_by_index(int i, std::string& Value, int offset) { if (has_common()) {untested(); COMMON_COMPONENT* c = common()->clone(); assert(c); c->set_param_by_index(i, Value, offset); attach_common(c); }else{ switch (COMPONENT::param_count() - 1 - i) { case 0: _value = Value; break; case 1: _mfactor = Value; break; default: CARD::set_param_by_index(i, Value, offset); } } } /*--------------------------------------------------------------------------*/ bool COMPONENT::param_is_printable(int i)const { if (has_common()) { return common()->param_is_printable(i); }else{ switch (COMPONENT::param_count() - 1 - i) { case 0: return value().has_hard_value(); case 1: return _mfactor.has_hard_value(); default: return CARD::param_is_printable(i); } } } /*--------------------------------------------------------------------------*/ std::string COMPONENT::param_name(int i)const { if (has_common()) { return common()->param_name(i); }else{ switch (COMPONENT::param_count() - 1 - i) { case 0: return value_name(); case 1: return "m"; default: return CARD::param_name(i); } } } /*--------------------------------------------------------------------------*/ std::string COMPONENT::param_name(int i, int j)const { if (has_common()) {untested(); return common()->param_name(i,j); }else{ if (j == 0) { return param_name(i); }else if (i >= CARD::param_count()) {untested(); return ""; }else{untested(); return CARD::param_name(i,j); } } } /*--------------------------------------------------------------------------*/ std::string COMPONENT::param_value(int i)const { if (has_common()) { return common()->param_value(i); }else{ switch (COMPONENT::param_count() - 1 - i) { case 0: return value().string(); case 1: return _mfactor.string(); default: return CARD::param_value(i); } } } /*--------------------------------------------------------------------------*/ const std::string COMPONENT::port_value(int i)const { assert(_n); assert(i >= 0); assert(i < net_nodes()); return _n[i].short_label(); } /*--------------------------------------------------------------------------*/ const std::string COMPONENT::current_port_value(int)const {untested(); unreachable(); static std::string s; return s; } /*--------------------------------------------------------------------------*/ double COMPONENT::tr_probe_num(const std::string& x)const { CS cmd(CS::_STRING, x); if (cmd.umatch("v")) { int nn = cmd.ctoi(); return (nn > 0 && nn <= net_nodes()) ? _n[nn-1].v0() : NOT_VALID; }else if (Umatch(x, "error{time} |next{time} ")) { return (_time_by._error_estimate < BIGBIG) ? _time_by._error_estimate : 0; }else if (Umatch(x, "timef{uture} ")) { return (_time_by._error_estimate < _time_by._event) ? _time_by._error_estimate : _time_by._event; }else if (Umatch(x, "event{time} ")) { return (_time_by._event < BIGBIG) ? _time_by._event : 0; }else{ return CARD::tr_probe_num(x); } } /*--------------------------------------------------------------------------*/ const MODEL_CARD* COMPONENT::find_model(const std::string& modelname)const { if (modelname == "") { throw Exception(long_label() + ": missing args -- need model name"); unreachable(); return NULL; }else{ const CARD* c = NULL; { int bin_count = 0; for (const CARD* Scope = this; Scope && !c; Scope = Scope->owner()) { // start here, looking out try { c = Scope->find_in_my_scope(modelname); }catch (Exception_Cant_Find& e1) { // didn't find plain model. try binned models bin_count = 0; for (;;) { // loop over binned models std::string extended_name = modelname + '.' + to_string(++bin_count); try { c = Scope->find_in_my_scope(extended_name); }catch (Exception_Cant_Find& e2) { // that's all .. looked at all of them c = NULL; break; } const MODEL_CARD* m = dynamic_cast(c); if (m && m->is_valid(this)) { //matching name and correct bin break; }else{ // keep looking } } } } if (!c) { if (bin_count <= 1) { throw Exception_Cant_Find(long_label(), modelname); }else{ throw Exception(long_label() + ": no bins match: " + modelname); } unreachable(); }else{ } } // found something, what is it? assert(c); const MODEL_CARD* model = dynamic_cast(c); if (!model) {untested(); throw Exception_Type_Mismatch(long_label(), modelname, ".model"); }else if (!model->is_valid(this)) {itested(); error(bWARNING, long_label() + ", " + modelname + "\nmodel and device parameters are incompatible, using anyway\n"); }else{ } assert(model); return model; } } /*--------------------------------------------------------------------------*/ /* q_eval: queue this device for evaluation on the next pass, * with a check against doing it twice. */ void COMPONENT::q_eval() { if(!is_q_for_eval()) { mark_q_for_eval(); _sim->_evalq_uc->push_back(this); }else{itested(); } } /*--------------------------------------------------------------------------*/ void COMPONENT::tr_queue_eval() { if(tr_needs_eval()) { q_eval(); }else{ } } /*--------------------------------------------------------------------------*/ TIME_PAIR COMPONENT::tr_review() { _time_by.reset(); if(has_common()) { return _common->tr_review(this); }else{ return _time_by; } } /*--------------------------------------------------------------------------*/ void COMPONENT::tr_accept() { if(has_common()) { _common->tr_accept(this); }else{ } } /*--------------------------------------------------------------------------*/ bool COMPONENT::use_obsolete_callback_parse()const { if (has_common()) { return common()->use_obsolete_callback_parse(); }else{ return false; } } /*--------------------------------------------------------------------------*/ bool COMPONENT::use_obsolete_callback_print()const { if (has_common()) { return common()->use_obsolete_callback_print(); }else{ return false; } } /*--------------------------------------------------------------------------*/ void COMPONENT::obsolete_move_parameters_from_common(const COMMON_COMPONENT* dc) { assert(dc); _value = dc->value(); _mfactor = dc->mfactor(); } /*--------------------------------------------------------------------------*/ /* volts_limited: transient voltage, best approximation, with limiting */ double COMPONENT::volts_limited(const node_t & n1, const node_t & n2) { bool limiting = false; double v1 = n1.v0(); assert(v1 == v1); if (v1 < _sim->_vmin) { limiting = true; v1 = _sim->_vmin; }else if (v1 > _sim->_vmax) { limiting = true; v1 = _sim->_vmax; } double v2 = n2.v0(); assert(v2 == v2); if (v2 < _sim->_vmin) { limiting = true; v2 = _sim->_vmin; }else if (v2 > _sim->_vmax) { limiting = true; v2 = _sim->_vmax; } if (limiting) { _sim->_limiting = true; if (OPT::dampstrategy & dsRANGE) { _sim->_fulldamp = true; error(bTRACE, "range limit damp\n"); } if (OPT::picky <= bTRACE) {untested(); error(bNOERROR,"node limiting (n1,n2,dif) " "was (%g %g %g) now (%g %g %g)\n", n1.v0(), n2.v0(), n1.v0() - n2.v0(), v1, v2, v1-v2); } } return dn_diff(v1,v2); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������src/e_compon.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000027607�11454012162�0013625�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_compon.h,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * base class for all components */ //testing=script 2007.07.13 #ifndef E_COMPON_H #define E_COMPON_H #include "u_sim_data.h" #include "u_time_pair.h" #include "u_parameter.h" #include "e_card.h" /*--------------------------------------------------------------------------*/ // this file class COMMON_COMPONENT; class COMPONENT; /*--------------------------------------------------------------------------*/ // external class MODEL_CARD; class CS; class ELEMENT; class CARD_LIST; /*--------------------------------------------------------------------------*/ inline bool conchk(double o, double n, double a=OPT::abstol, double r=OPT::reltol) { return (std::abs(n-o) <= (r * std::abs(n) + a)); } /*--------------------------------------------------------------------------*/ struct Exception_Precalc :public Exception{ Exception_Precalc(const std::string& Message) :Exception(Message) { } }; /*--------------------------------------------------------------------------*/ enum {CC_STATIC=27342}; // mid-sized arbitrary positive int // pass this as an argument to a common constructor to mark it as static, // so it won't be deleted /*--------------------------------------------------------------------------*/ class INTERFACE COMMON_COMPONENT { protected: PARAMETER _tnom_c; // specification temperature PARAMETER _dtemp; // rise over enclosing temperature PARAMETER _temp_c; // actual temperature of device PARAMETER _mfactor; // number of devices in parallel PARAMETER _value; private: std::string _modelname; mutable const MODEL_CARD* _model; int _attach_count; public: static void attach_common(COMMON_COMPONENT* c, COMMON_COMPONENT** to); static void detach_common(COMMON_COMPONENT** from); private: COMMON_COMPONENT& operator=(const COMMON_COMPONENT&) {unreachable(); return *this;} explicit COMMON_COMPONENT() {unreachable();incomplete();} protected: explicit COMMON_COMPONENT(const COMMON_COMPONENT& p); explicit COMMON_COMPONENT(int c); public: virtual ~COMMON_COMPONENT(); void attach_model(const COMPONENT*)const; COMMON_COMPONENT& attach(const MODEL_CARD* m) {_model = m; return *this;} void set_modelname(const std::string& n) {_modelname = n;} void parse_modelname(CS&); virtual COMMON_COMPONENT* clone()const = 0; virtual bool use_obsolete_callback_parse()const {return false;} virtual bool use_obsolete_callback_print()const {return false;} virtual void parse_common_obsolete_callback(CS&); virtual void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const; virtual bool has_parse_params_obsolete_callback()const {return false;} virtual bool is_trivial()const {return false;} virtual bool param_is_printable(int)const; virtual std::string param_name(int)const; virtual std::string param_name(int,int)const; virtual std::string param_value(int)const; virtual void set_param_by_name(std::string, std::string); void Set_param_by_name(std::string, std::string); //BUG// see implementation virtual void set_param_by_index(int, std::string&, int); virtual int param_count()const {return 4;} public: virtual void precalc_first(const CARD_LIST*); virtual void expand(const COMPONENT*) {} virtual COMMON_COMPONENT* deflate() {return this;} virtual void precalc_last(const CARD_LIST*) {} virtual void tr_eval(ELEMENT*)const; virtual void ac_eval(ELEMENT*)const; virtual TIME_PAIR tr_review(COMPONENT*) {return TIME_PAIR(NEVER,NEVER);} virtual void tr_accept(COMPONENT*) {} virtual bool has_tr_eval()const {untested(); return false;} virtual bool has_ac_eval()const {untested(); return false;} virtual bool parse_numlist(CS&); virtual bool parse_params_obsolete_callback(CS&); virtual void skip_type_tail(CS&)const {} virtual std::string name()const = 0; virtual bool operator==(const COMMON_COMPONENT&x)const; bool operator!=(const COMMON_COMPONENT& x)const {return !(*this == x);} std::string modelname()const {return _modelname;} const MODEL_CARD* model()const {assert(_model); return _model;} bool has_model()const {return _model;} const PARAMETER& mfactor()const {return _mfactor;} const PARAMETER& value()const {return _value;} private: bool parse_param_list(CS&); }; /*--------------------------------------------------------------------------*/ /* note on _attach_count ... * The int argument is the initial _attach_count (default = 0) * Set it to CC_STATIC for static default versions that will never be deleted. * Set it to 0 (default) for auto versions, so they can be deleted. * A common will not be deleted on a detach if its _attach_count != 0 * A failed assertion from the common destructor probably means * the common is being deleted before a device it is attached to is, * without being first detached. * This is why ~COMPONENT destroys the subckt explicitly. * * Static commons (CC_STATIC) must be in file scope, not in function scope, * because local statics are deleted first, before any globals. * //BUG// possible portability problem. What is deletion order? */ /*--------------------------------------------------------------------------*/ class INTERFACE COMPONENT : public CARD { private: COMMON_COMPONENT* _common; protected: PARAMETER _value; // value, for simple parts PARAMETER _mfactor; // number of devices in parallel private: double _mfactor_fixed; // composite, including subckt mfactor bool _converged; int _q_for_eval; public: TIME_PAIR _time_by; //-------------------------------------------------------------------- protected: // create and destroy. explicit COMPONENT(); explicit COMPONENT(const COMPONENT& p); ~COMPONENT(); //-------------------------------------------------------------------- public: // "elaborate" void precalc_first(); void expand(); void precalc_last(); //-------------------------------------------------------------------- public: // dc-tran void tr_iwant_matrix(); void tr_queue_eval(); TIME_PAIR tr_review(); void tr_accept(); double tr_probe_num(const std::string&)const; //-------------------------------------------------------------------- public: // ac void ac_iwant_matrix(); //-------------------------------------------------------------------- public: // state, aux data bool is_device()const {return true;} void set_slave(); void map_nodes(); virtual const std::string current_probe_name()const {untested(); return "";} static double volts_limited(const node_t& n1, const node_t& n2); bool converged()const {return _converged;} void set_converged(bool s=true) {_converged = s;} void set_not_converged() {_converged = false;} double mfactor()const { assert(_mfactor_fixed != NOT_VALID); if (const COMPONENT* o = prechecked_cast(owner())) { assert(_mfactor_fixed == o->mfactor() * _mfactor); }else{ assert(_mfactor_fixed == _mfactor); } return _mfactor_fixed; } //-------------------------------------------------------------------- // list and queue management bool is_q_for_eval()const {return (_q_for_eval >= _sim->iteration_tag());} void mark_q_for_eval() {_q_for_eval = _sim->iteration_tag();} void mark_always_q_for_eval() {_q_for_eval = INT_MAX;} void q_eval(); void q_load() {_sim->_loadq.push_back(this);} void q_accept() {_sim->_acceptq.push_back(this);} //-------------------------------------------------------------------- // model const MODEL_CARD* find_model(const std::string& name)const; void attach_model()const {assert(has_common()); _common->attach_model(this);} //-------------------------------------------------------------------- // common COMMON_COMPONENT* mutable_common() {return _common;} const COMMON_COMPONENT* common()const {return _common;} bool has_common()const {return _common;} void attach_common(COMMON_COMPONENT*c) {COMMON_COMPONENT::attach_common(c,&_common);} void detach_common() {COMMON_COMPONENT::detach_common(&_common);} void deflate_common(); //-------------------------------------------------------------------- public: // type void set_dev_type(const std::string& new_type); //-------------------------------------------------------------------- public: // ports virtual std::string port_name(int)const = 0; virtual void set_port_by_name(std::string& name, std::string& value); virtual void set_port_by_index(int index, std::string& value); bool port_exists(int i)const {return i < net_nodes();} const std::string port_value(int i)const; void set_port_to_ground(int index); virtual std::string current_port_name(int)const {return "";} virtual const std::string current_port_value(int)const; virtual void set_current_port_by_index(int, const std::string&) {unreachable();} bool current_port_exists(int i)const {return i < num_current_ports();} virtual int max_nodes()const {unreachable(); return 0;} virtual int min_nodes()const {unreachable(); return 0;} virtual int num_current_ports()const {return 0;} virtual int tail_size()const {return 0;} virtual int net_nodes()const {untested();return 0;} //override virtual int ext_nodes()const {return max_nodes();} virtual int int_nodes()const {return 0;} virtual int matrix_nodes()const {return 0;} virtual bool has_inode()const {return false;} virtual bool has_iv_probe()const {return false;} virtual bool is_source()const {return false;} virtual bool f_is_value()const {return false;} bool node_is_grounded(int i)const; virtual bool node_is_connected(int i)const; //-------------------------------------------------------------------- public: // parameters void set_param_by_name(std::string, std::string); void set_param_by_index(int, std::string&, int); int param_count()const {return ((has_common()) ? (common()->param_count()) : (2 + CARD::param_count()));} bool param_is_printable(int)const; std::string param_name(int)const; std::string param_name(int,int)const; std::string param_value(int)const; virtual void set_parameters(const std::string& Label, CARD* Parent, COMMON_COMPONENT* Common, double Value, int state_count, double state[], int node_count, const node_t nodes[]); void set_value(const PARAMETER& v) {_value = v;} void set_value(double v) {_value = v;} void set_value(const std::string& v) {untested(); _value = v;} void set_value(double v, COMMON_COMPONENT* c); const PARAMETER& value()const {return _value;} //-------------------------------------------------------------------- public: // obsolete -- do not use in new code virtual bool print_type_in_spice()const = 0; bool use_obsolete_callback_parse()const; bool use_obsolete_callback_print()const; void print_args_obsolete_callback(OMSTREAM&, LANGUAGE*)const; void obsolete_move_parameters_from_common(const COMMON_COMPONENT*); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif �������������������������������������������������������������������������������������������������������������������������src/e_elemnt.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000036032�11454012162�0013744�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_elemnt.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Base class for elements of a circuit */ //testing=script 2006.07.12 #include "m_divdiff.h" #include "u_xprobe.h" #include "e_aux.h" #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ ELEMENT::ELEMENT() :COMPONENT(), _loaditer(0), _m0(), _m1(), _loss0(0.), _loss1(0.), _acg(0.), _ev(0.), _dt(0.) { _n = _nodes; assert(_y[0].x == 0. && _y[0].f0 == 0. && _y[0].f1 == 0.); assert(_y1 == _y[0]); std::fill_n(_time, int(OPT::_keep_time_steps), 0.); } /*--------------------------------------------------------------------------*/ ELEMENT::ELEMENT(const ELEMENT& p) :COMPONENT(p), _loaditer(0), _m0(), _m1(), _loss0(p._loss0), _loss1(p._loss1), _acg(0.), _ev(0.), _dt(0.) { trace0(long_label().c_str()); _n = _nodes; if (p._n == p._nodes) { for (int ii = 0; ii < NODES_PER_BRANCH; ++ii) { _n[ii] = p._n[ii]; } }else{ assert(p._nodes); // the constructor for a derived class will take care of it } assert(_y[0].x == 0. && _y[0].f0 == 0. && _y[0].f1 == 0.); assert(_y1 == _y[0]); notstd::copy_n(p._time, int(OPT::_keep_time_steps), _time); } /*--------------------------------------------------------------------------*/ bool ELEMENT::skip_dev_type(CS& cmd) { return cmd.umatch(dev_type() + ' '); } /*--------------------------------------------------------------------------*/ void ELEMENT::precalc_last() { COMPONENT::precalc_last(); //BUG// This is needed for AC analysis without doing op (or dc or tran ...) first. // Something like it should be moved to ac_begin. if (_sim->is_first_expand()) { _y[0].x = 0.; _y[0].f0 = LINEAR; _y[0].f1 = value(); }else{ } } /*--------------------------------------------------------------------------*/ void ELEMENT::tr_begin() { _time[0] = 0.; _y[0].x = 0.; _y[0].f0 = LINEAR; _y[0].f1 = value(); _y1 = _y[0]; for (int i=1; i _sim->_time0) {itested(); for (int i=0 ; i_time0) { }else{untested(); } //assert(_time[0] == _sim->_time0); if (_time[0] != _sim->_time0) {itested(); error(bDANGER, "//BUG// restore time mismatch. last=%g, using=%g\n", _time[0], _sim->_time0); //BUG// happens when continuing after a ^c, // when the last step was not printed // _time[0] is the non-printed time. _sim->_time0 is the printed time. }else{ } for (int i=OPT::_keep_time_steps-1; i>0; --i) { assert(_time[i] < _time[i-1] || _time[i] == 0.); } } /*--------------------------------------------------------------------------*/ void ELEMENT::dc_advance() { assert(_sim->_time0 == 0.); // DC for (int i=OPT::_keep_time_steps-1; i>=0; --i) { assert(_time[i] == 0.); } _dt = NOT_VALID; } /*--------------------------------------------------------------------------*/ void ELEMENT::tr_advance() { assert(_time[0] < _sim->_time0); // moving forward for (int i=OPT::_keep_time_steps-1; i>0; --i) { assert(_time[i] < _time[i-1] || _time[i] == 0.); _time[i] = _time[i-1]; _y[i] = _y[i-1]; } _time[0] = _sim->_time0; _dt = _time[0] - _time[1]; } /*--------------------------------------------------------------------------*/ void ELEMENT::tr_regress() { assert(_time[0] >= _sim->_time0); // moving backwards assert(_time[1] <= _sim->_time0); // but not too far backwards for (int i=OPT::_keep_time_steps-1; i>0; --i) { assert(_time[i] < _time[i-1] || _time[i] == 0.); } _time[0] = _sim->_time0; _dt = _time[0] - _time[1]; } /*--------------------------------------------------------------------------*/ TIME_PAIR ELEMENT::tr_review() { COMPONENT::tr_review(); if (order() > 0 && _y[0].f0 != LINEAR) { double timestep = tr_review_trunc_error(_y); double newtime = tr_review_check_and_convert(timestep); _time_by.min_error_estimate(newtime); }else{ } return _time_by; } /*--------------------------------------------------------------------------*/ void ELEMENT::tr_iwant_matrix_passive() { assert(matrix_nodes() == 2); assert(is_device()); //assert(!subckt()); ok for subckt to exist for logic trace2(long_label().c_str(), _n[OUT1].m_(), _n[OUT2].m_()); assert(_n[OUT1].m_() != INVALID_NODE); assert(_n[OUT2].m_() != INVALID_NODE); _sim->_aa.iwant(_n[OUT1].m_(),_n[OUT2].m_()); _sim->_lu.iwant(_n[OUT1].m_(),_n[OUT2].m_()); } /*--------------------------------------------------------------------------*/ void ELEMENT::tr_iwant_matrix_active() { assert(matrix_nodes() == 4); assert(is_device()); assert(!subckt()); assert(_n[OUT1].m_() != INVALID_NODE); assert(_n[OUT2].m_() != INVALID_NODE); assert(_n[IN1].m_() != INVALID_NODE); assert(_n[IN2].m_() != INVALID_NODE); //_sim->_aa.iwant(_n[OUT1].m_(),_n[OUT2].m_()); _sim->_aa.iwant(_n[OUT1].m_(),_n[IN1].m_()); _sim->_aa.iwant(_n[OUT1].m_(),_n[IN2].m_()); _sim->_aa.iwant(_n[OUT2].m_(),_n[IN1].m_()); _sim->_aa.iwant(_n[OUT2].m_(),_n[IN2].m_()); //_sim->_aa.iwant(_n[IN1].m_(),_n[IN2].m_()); //_sim->_lu.iwant(_n[OUT1].m_(),_n[OUT2].m_()); _sim->_lu.iwant(_n[OUT1].m_(),_n[IN1].m_()); _sim->_lu.iwant(_n[OUT1].m_(),_n[IN2].m_()); _sim->_lu.iwant(_n[OUT2].m_(),_n[IN1].m_()); _sim->_lu.iwant(_n[OUT2].m_(),_n[IN2].m_()); //_sim->_lu.iwant(_n[IN1].m_(),_n[IN2].m_()); } /*--------------------------------------------------------------------------*/ void ELEMENT::tr_iwant_matrix_extended() { assert(is_device()); assert(!subckt()); assert(ext_nodes() + int_nodes() == matrix_nodes()); for (int ii = 0; ii < matrix_nodes(); ++ii) { if (_n[ii].m_() >= 0) { for (int jj = 0; jj < ii ; ++jj) { _sim->_aa.iwant(_n[ii].m_(),_n[jj].m_()); _sim->_lu.iwant(_n[ii].m_(),_n[jj].m_()); } }else{itested(); // node 1 is grounded or invalid } } } /*--------------------------------------------------------------------------*/ void ELEMENT::ac_iwant_matrix_passive() { trace2(long_label().c_str(), _n[OUT1].m_(), _n[OUT2].m_()); _sim->_acx.iwant(_n[OUT1].m_(),_n[OUT2].m_()); } /*--------------------------------------------------------------------------*/ void ELEMENT::ac_iwant_matrix_active() { //_sim->_acx.iwant(_n[OUT1].m_(),_n[OUT2].m_()); _sim->_acx.iwant(_n[OUT1].m_(),_n[IN1].m_()); _sim->_acx.iwant(_n[OUT1].m_(),_n[IN2].m_()); _sim->_acx.iwant(_n[OUT2].m_(),_n[IN1].m_()); _sim->_acx.iwant(_n[OUT2].m_(),_n[IN2].m_()); //_sim->_acx.iwant(_n[IN1].m_(),_n[IN2].m_()); } /*--------------------------------------------------------------------------*/ void ELEMENT::ac_iwant_matrix_extended() { assert(is_device()); assert(!subckt()); assert(ext_nodes() + int_nodes() == matrix_nodes()); for (int ii = 0; ii < matrix_nodes(); ++ii) { if (_n[ii].m_() >= 0) { for (int jj = 0; jj < ii ; ++jj) { _sim->_acx.iwant(_n[ii].m_(),_n[jj].m_()); } }else{itested(); // node 1 is grounded or invalid } } } /*--------------------------------------------------------------------------*/ double ELEMENT::tr_amps()const { trace5("", _loss0, tr_outvolts(), _m0.c1, tr_involts(), _m0.c0); return fixzero((_loss0 * tr_outvolts() + _m0.c1 * tr_involts() + _m0.c0), _m0.c0); } /*--------------------------------------------------------------------------*/ double ELEMENT::tr_probe_num(const std::string& x)const { if (Umatch(x, "v{out} ")) { return tr_outvolts(); }else if (Umatch(x, "vi{n} ")) { return tr_involts(); }else if (Umatch(x, "i ")) { return tr_amps(); }else if (Umatch(x, "p ")) { return tr_amps() * tr_outvolts(); }else if (Umatch(x, "pd ")) { double p = tr_amps() * tr_outvolts(); return (p > 0.) ? p : 0.; }else if (Umatch(x, "ps ")) { double p = tr_amps() * tr_outvolts(); return (p < 0.) ? -p : 0.; }else if (Umatch(x, "in{put} ")) { return _y[0].x; }else if (Umatch(x, "f ")) { if (_y[0].f0 == LINEAR) {itested(); return _y[0].x * _y[0].f1; }else{ return _y[0].f0; } }else if (Umatch(x, "ev |df ")) { return _y[0].f1; }else if (Umatch(x, "nv ")) { return value(); }else if (Umatch(x, "eiv ")) {untested(); return _m0.x; }else if (Umatch(x, "y ")) { return _m0.c1; }else if (Umatch(x, "is{tamp} ")) { return _m0.f0(); }else if (Umatch(x, "iof{fset} ")) {itested(); return _m0.c0; }else if (Umatch(x, "ip{assive} ")) {itested(); return _m0.c1 * tr_involts(); }else if (Umatch(x, "il{oss} ")) {untested(); return _loss0 * tr_outvolts(); }else if (Umatch(x, "dt ")) { return _dt; }else if (Umatch(x, "dtr{equired} ")) { return ((_time_by._error_estimate - _time[0]) > 0) ? _time_by._error_estimate - _time[0] : _time_by._error_estimate - _time[1]; }else if (Umatch(x, "time ")) {untested(); return _time[0]; }else if (Umatch(x, "timeo{ld} ")) {untested(); return _time[1]; //}else if (Umatch(x, "didt ")) {untested(); //double i0 = (_m0.c1 * _m0.x + _m0.c0); //double it1 = (mt1.f1 * mt1.x + mt1.c0); //return (i0 - it1) / (_sim->_time0 - _time1); }else if (Umatch(x, "r ")) { return (_m0.c1!=0.) ? 1/_m0.c1 : MAXDBL; }else if (Umatch(x, "z ")) { return port_impedance(_n[OUT1], _n[OUT2], _sim->_lu, mfactor()*(_m0.c1+_loss0)); }else if (Umatch(x, "zraw ")) { return port_impedance(_n[OUT1], _n[OUT2], _sim->_lu, 0.); }else{ return COMPONENT::tr_probe_num(x); } } /*--------------------------------------------------------------------------*/ COMPLEX ELEMENT::ac_amps()const { assert(!is_source()); return (ac_involts() * _acg + ac_outvolts() * _loss0); } /*--------------------------------------------------------------------------*/ XPROBE ELEMENT::ac_probe_ext(const std::string& x)const { COMPLEX admittance = (is_source()) ? _loss0 : _acg+_loss0; if (Umatch(x, "v{out} ")) { /* volts (out) */ return XPROBE(ac_outvolts()); }else if (Umatch(x, "vin ")) { /* volts (in) */ return XPROBE(ac_involts()); }else if (Umatch(x, "i ")) { /* amps */ return XPROBE(ac_amps()); }else if (Umatch(x, "p ")) { /* complex "power" */ return XPROBE(ac_outvolts() * conj(ac_amps()), mtREAL, 10.); }else if (Umatch(x, "nv ")) {untested(); /* nominal value */ return XPROBE(value()); }else if (Umatch(x, "ev ")) { /* effective value */ return XPROBE(_ev); }else if (Umatch(x, "y ")) {untested(); /* admittance */ return XPROBE(admittance, mtREAL); }else if (Umatch(x, "r ")) { /* complex "resistance" */ if (admittance == 0.) {untested(); return XPROBE(MAXDBL); }else{untested(); return XPROBE(1. / admittance); } }else if (Umatch(x, "z ")) { /* port impedance */ return XPROBE(port_impedance(_n[OUT1], _n[OUT2], _sim->_acx, mfactor()*admittance)); }else if (Umatch(x, "zraw ")) { /* port impedance, raw */ return XPROBE(port_impedance(_n[OUT1], _n[OUT2], _sim->_acx, COMPLEX(0.))); }else{ /* bad parameter */ return COMPONENT::ac_probe_ext(x); } } /*--------------------------------------------------------------------------*/ double ELEMENT::tr_review_trunc_error(const FPOLY1* q) { int error_deriv = order()+1; double timestep; if (_time[0] <= 0.) { // DC, I know nothing timestep = NEVER; }else if (_time[error_deriv] <= 0.) { // first few steps, I still know nothing // repeat whatever step was used the first time timestep = _dt; }else{ for (int i=error_deriv; i>0; --i) { assert(_time[i] < _time[i-1]); // || _time[i] == 0.); } double c[OPT::_keep_time_steps]; for (int i=0; i= 5); trace0(("ts" + long_label()).c_str()); trace5("time", _time[0], _time[1], _time[2], _time[3], _time[4]); trace5("charge", q[0].f0, q[1].f0, q[2].f0, q[3].f0, q[4].f0); trace5("deriv", c[0], c[1], c[2], c[3], c[4]); if (c[error_deriv] == 0) { timestep = NEVER; }else{ double chargetol = std::max(OPT::chgtol, OPT::reltol * std::max(std::abs(q[0].f0), std::abs(q[1].f0))); double tol = OPT::trtol * chargetol; double denom = error_factor() * std::abs(c[error_deriv]); assert(tol > 0.); assert(denom > 0.); switch (error_deriv) { // pow is slow. case 1: timestep = tol / denom; break; case 2: timestep = sqrt(tol / denom); break; case 3: timestep = cbrt(tol / denom); break; default: timestep = pow((tol / denom), 1./(error_deriv)); break; } trace4("", chargetol, tol, denom, timestep); } } assert(timestep > 0.); return timestep; } /*--------------------------------------------------------------------------*/ double ELEMENT::tr_review_check_and_convert(double timestep) { double time_future; if (timestep == NEVER) { time_future = NEVER; }else{ if (timestep < _sim->_dtmin) { timestep = _sim->_dtmin; }else{ } if (timestep < _dt * OPT::trreject) { if (_time[order()] == 0) { error(bWARNING, "initial step rejected:" + long_label() + '\n'); error(bWARNING, "new=%g old=%g required=%g\n", timestep, _dt, _dt * OPT::trreject); }else{ error(bTRACE, "step rejected:" + long_label() + '\n'); error(bTRACE, "new=%g old=%g required=%g\n", timestep, _dt, _dt * OPT::trreject); } time_future = _time[1] + timestep; trace3("reject", timestep, _dt, time_future); }else{ time_future = _time[0] + timestep; trace3("accept", timestep, _dt, time_future); } } assert(time_future > 0.); assert(time_future > _time[1]); return time_future; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/e_elemnt.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000035104�11454012162�0013605�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_elemnt.h,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * base class for simple elements */ //testing=script 2006.07.12 #ifndef E_ELEMNT_H #define E_ELEMNT_H #include "e_node.h" #include "m_cpoly.h" #include "l_denoise.h" #include "e_compon.h" /*--------------------------------------------------------------------------*/ class INTERFACE ELEMENT : public COMPONENT { protected: explicit ELEMENT(); explicit ELEMENT(const ELEMENT& p); ~ELEMENT() {} void store_values() {assert(_y[0]==_y[0]); _y1=_y[0];} //void reject_values() { _y0 = _y1;} public: double* set__value() {return _value.pointer_hack();} bool skip_dev_type(CS&); public: // override virtual bool print_type_in_spice()const {return false;} void precalc_last(); void tr_begin(); void tr_restore(); void dc_advance(); void tr_advance(); void tr_regress(); bool tr_needs_eval()const {/*assert(!is_q_for_eval());*/ return !is_constant();} #if 0 void tr_queue_eval() { if(tr_needs_eval()) { q_eval(); }else{ } } #endif TIME_PAIR tr_review(); //void map_nodes(); void tr_iwant_matrix() = 0; void ac_iwant_matrix() = 0; double tr_probe_num(const std::string&)const; XPROBE ac_probe_ext(const std::string&)const; protected: // inline, below double dampdiff(double*, const double&); void tr_load_inode(); void tr_unload_inode(); void ac_load_inode(); void tr_load_shunt(); void tr_unload_shunt(); void ac_load_shunt(); void tr_load_source(); void tr_unload_source(); void ac_load_source(); void tr_load_couple(); void tr_unload_couple(); void ac_load_couple(); void tr_load_passive(); void tr_unload_passive(); void ac_load_passive(); void tr_load_active(); void tr_unload_active(); void ac_load_active(); void tr_load_extended(const node_t& no1, const node_t& no2, const node_t& ni1, const node_t& ni2, double* value, double* old_value); void ac_load_extended(const node_t& no1, const node_t& no2, const node_t& ni1, const node_t& ni2, COMPLEX value); void tr_load_source_point(node_t& no1, double* value, double* old_value); void ac_load_source_point(node_t& no1, COMPLEX new_value); void tr_load_diagonal_point(const node_t& no1, double* value, double* old_value); void ac_load_diagonal_point(const node_t& no1, COMPLEX value); void tr_load_point(const node_t& no1, const node_t& no2, double* value, double* old_value); void ac_load_point(const node_t& no1, const node_t& no2, COMPLEX value); bool conv_check()const; bool has_tr_eval()const; bool has_ac_eval()const; bool using_tr_eval()const; bool using_ac_eval()const; void tr_eval(); void ac_eval(); protected: // in .cc void tr_iwant_matrix_passive(); void tr_iwant_matrix_active(); void tr_iwant_matrix_extended(); void ac_iwant_matrix_passive(); void ac_iwant_matrix_active(); void ac_iwant_matrix_extended(); public: double tr_review_trunc_error(const FPOLY1* q); double tr_review_check_and_convert(double timestep); double tr_outvolts()const {return dn_diff(_n[OUT1].v0(), _n[OUT2].v0());} double tr_outvolts_limited()const{return volts_limited(_n[OUT1],_n[OUT2]);} COMPLEX ac_outvolts()const {return _n[OUT1]->vac() - _n[OUT2]->vac();} virtual double tr_involts()const = 0; virtual double tr_input()const {return tr_involts();} virtual double tr_involts_limited()const = 0; virtual double tr_input_limited()const {return tr_involts_limited();} virtual double tr_amps()const; virtual COMPLEX ac_involts()const = 0; virtual COMPLEX ac_amps()const; virtual int order()const {return OPT::trsteporder;} virtual double error_factor()const {return OPT::trstepcoef[OPT::trsteporder];} int param_count()const {return (0 + COMPONENT::param_count());} protected: int _loaditer; // load iteration number private: node_t _nodes[NODES_PER_BRANCH]; // nodes (0,1:out, 2,3:in) public: CPOLY1 _m0; // matrix parameters, new CPOLY1 _m1; // matrix parameters, 1 fill ago double _loss0; // shunt conductance double _loss1; COMPLEX _acg; // ac admittance matrix values public: // commons COMPLEX _ev; // ac effective value (usually real) double _dt; double _time[OPT::_keep_time_steps]; FPOLY1 _y1; // iteration parameters, 1 iter ago FPOLY1 _y[OPT::_keep_time_steps]; /* charge or flux, and deriv. */ }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ inline double ELEMENT::dampdiff(double* v0, const double& v1) { //double diff = v0 - v1; assert(v0); assert(*v0 == *v0); assert(v1 == v1); double diff = dn_diff(*v0, v1); assert(diff == diff); if (!_sim->is_advance_or_first_iteration()) { diff *= _sim->_damp; *v0 = v1 + diff; }else{ } return mfactor() * ((_sim->is_inc_mode()) ? diff : *v0); } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_load_inode() { double d = dampdiff(&_loss0, _loss1); if (d != 0.) { _sim->_aa.load_couple(_n[OUT1].m_(), _n[IN1].m_(), -d); _sim->_aa.load_couple(_n[OUT2].m_(), _n[IN1].m_(), d); }else{ } _loss1 = _loss0; } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_unload_inode() {untested(); _loss0 = 0.; _sim->mark_inc_mode_bad(); tr_load_inode(); } /*--------------------------------------------------------------------------*/ inline void ELEMENT::ac_load_inode() { _sim->_acx.load_couple(_n[OUT1].m_(), _n[IN1].m_(), -mfactor() * _loss0); _sim->_acx.load_couple(_n[OUT2].m_(), _n[IN1].m_(), mfactor() * _loss0); } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_load_shunt() { double d = dampdiff(&_loss0, _loss1); if (d != 0.) { _sim->_aa.load_symmetric(_n[OUT1].m_(), _n[OUT2].m_(), d); }else{ } _loss1 = _loss0; } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_unload_shunt() {untested(); _loss0 = 0.; _sim->mark_inc_mode_bad(); tr_load_shunt(); } /*--------------------------------------------------------------------------*/ inline void ELEMENT::ac_load_shunt() { _sim->_acx.load_symmetric(_n[OUT1].m_(), _n[OUT2].m_(), mfactor() * _loss0); } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_load_source() { #if !defined(NDEBUG) assert(_loaditer != _sim->iteration_tag()); // double load _loaditer = _sim->iteration_tag(); #endif double d = dampdiff(&_m0.c0, _m1.c0); if (d != 0.) { if (_n[OUT2].m_() != 0) { _n[OUT2].i() += d; }else{ } if (_n[OUT1].m_() != 0) { _n[OUT1].i() -= d; }else{ } }else{ } _m1 = _m0; } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_unload_source() {untested(); _m0.c0 = _m0.c1 = 0.; _sim->mark_inc_mode_bad(); tr_load_source(); } /*--------------------------------------------------------------------------*/ inline void ELEMENT::ac_load_source() { if (_n[OUT2].m_() != 0) { _n[OUT2]->iac() += mfactor() * _acg; }else{ } if (_n[OUT1].m_() != 0) { _n[OUT1]->iac() -= mfactor() * _acg; }else{itested(); } } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_load_couple() { double d = dampdiff(&_m0.c1, _m1.c1); if (d != 0.) { _sim->_aa.load_couple(_n[OUT1].m_(), _n[OUT2].m_(), d); }else{ } _m1.c1 = _m0.c1; } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_unload_couple() {untested(); _m0.c0 = _m0.c1 = 0.; _sim->mark_inc_mode_bad(); tr_load_couple(); // includes _m1 = _m0 } /*--------------------------------------------------------------------------*/ inline void ELEMENT::ac_load_couple() { _sim->_acx.load_couple(_n[OUT1].m_(), _n[OUT2].m_(), mfactor() * _acg); } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_load_passive() { double d = dampdiff(&_m0.c1, _m1.c1); if (d != 0.) { _sim->_aa.load_symmetric(_n[OUT1].m_(), _n[OUT2].m_(), d); }else{ } tr_load_source(); // includes _m1 = _m0 } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_unload_passive() { _m0.c0 = _m0.c1 = 0.; _sim->mark_inc_mode_bad(); tr_load_passive(); // includes _m1 = _m0 } /*--------------------------------------------------------------------------*/ inline void ELEMENT::ac_load_passive() { _sim->_acx.load_symmetric(_n[OUT1].m_(), _n[OUT2].m_(), mfactor() * _acg); } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_load_active() { double d = dampdiff(&_m0.c1, _m1.c1); if (d != 0.) { _sim->_aa.load_asymmetric(_n[OUT1].m_(), _n[OUT2].m_(), _n[IN1].m_(), _n[IN2].m_(), d); }else{ } tr_load_source(); // includes _m1 = _m0 } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_unload_active() {untested(); _m0.c0 = _m0.c1 = 0.; _sim->mark_inc_mode_bad(); tr_load_active(); // includes _m1 = _m0 } /*--------------------------------------------------------------------------*/ inline void ELEMENT::ac_load_active() { _sim->_acx.load_asymmetric(_n[OUT1].m_(), _n[OUT2].m_(), _n[IN1].m_(), _n[IN2].m_(), mfactor() * _acg); } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_load_extended(const node_t& no1, const node_t& no2, const node_t& ni1, const node_t& ni2, double* new_value, double* old_value) { double d = dampdiff(new_value, *old_value); if (d != 0.) { _sim->_aa.load_asymmetric(no1.m_(), no2.m_(), ni1.m_(), ni2.m_(), d); }else{ } *old_value = *new_value; } /*--------------------------------------------------------------------------*/ inline void ELEMENT::ac_load_extended(const node_t& no1, const node_t& no2, const node_t& ni1, const node_t& ni2, COMPLEX new_value) { _sim->_acx.load_asymmetric(no1.m_(), no2.m_(), ni1.m_(), ni2.m_(), mfactor() * new_value); } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_load_source_point(node_t& no1, double* new_value, double* old_value) { double d = dampdiff(new_value, *old_value); if (d != 0.) { if (no1.m_() != 0) { no1.i() += d; }else{ } }else{ } *old_value = *new_value; } /*--------------------------------------------------------------------------*/ inline void ELEMENT::ac_load_source_point(node_t& no1, COMPLEX new_value) {itested(); if (no1.m_() != 0) {itested(); no1->iac() += mfactor() * new_value; }else{itested(); } } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_load_diagonal_point(const node_t& no1, double* new_value, double* old_value) { double d = dampdiff(new_value, *old_value); if (d != 0.) { _sim->_aa.load_diagonal_point(no1.m_(), d); }else{ } *old_value = *new_value; } /*--------------------------------------------------------------------------*/ inline void ELEMENT::ac_load_diagonal_point(const node_t& no1, COMPLEX new_value) { _sim->_acx.load_diagonal_point(no1.m_(), mfactor() * new_value); } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_load_point(const node_t& no1, const node_t& no2, double* new_value, double* old_value) { double d = dampdiff(new_value, *old_value); if (d != 0.) { _sim->_aa.load_point(no1.m_(), no2.m_(), d); }else{ } *old_value = *new_value; } /*--------------------------------------------------------------------------*/ inline void ELEMENT::ac_load_point(const node_t& no1, const node_t& no2, COMPLEX new_value) {itested(); _sim->_acx.load_point(no1.m_(), no2.m_(), mfactor() * new_value); } /*--------------------------------------------------------------------------*/ inline bool ELEMENT::conv_check()const { return conchk(_y1.f1, _y[0].f1) && conchk(_y1.f0, _y[0].f0) && conchk(_y1.x, _y[0].x, OPT::vntol); } /*--------------------------------------------------------------------------*/ inline bool ELEMENT::has_tr_eval()const { return (has_common() && common()->has_tr_eval()); } /*--------------------------------------------------------------------------*/ inline bool ELEMENT::has_ac_eval()const { return (has_common() && common()->has_ac_eval()); } /*--------------------------------------------------------------------------*/ inline bool ELEMENT::using_tr_eval()const { return (has_probes() || has_tr_eval()); } /*--------------------------------------------------------------------------*/ inline bool ELEMENT::using_ac_eval()const { return (has_probes() || has_ac_eval()); } /*--------------------------------------------------------------------------*/ inline void ELEMENT::tr_eval() { if (has_tr_eval()) { common()->tr_eval(this); }else{ // can get here if a simple device has probes _y[0].f1 = value(); _y[0].f0 = _y[0].x * _y[0].f1; } set_converged(conv_check()); } /*--------------------------------------------------------------------------*/ inline void ELEMENT::ac_eval() { if (has_ac_eval()) { common()->ac_eval(this); }else{ // can get here if a simple device has probes _ev = _y[0].f1; } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/e_model.cc��������������������������������������������������������������������������������������0000664�0000000�0000000�00000006446�11454012162�0013566�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_model.cc,v 26.132 2009/11/24 04:26:37 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * base class for all models */ //testing=script 2006.07.12 #include "e_compon.h" #include "e_model.h" /*--------------------------------------------------------------------------*/ MODEL_CARD::MODEL_CARD(const COMPONENT* p) :CARD(), _component_proto(p), _tnom_c(NOT_INPUT) { _sim->uninit(); } /*--------------------------------------------------------------------------*/ MODEL_CARD::MODEL_CARD(const MODEL_CARD& p) :CARD(p), _component_proto(p._component_proto), _tnom_c(p._tnom_c) { _sim->uninit(); } /*--------------------------------------------------------------------------*/ MODEL_CARD::~MODEL_CARD() { _sim->uninit(); // disconnect models from devices } /*--------------------------------------------------------------------------*/ void MODEL_CARD::set_param_by_index(int i, std::string& value, int offset) { switch (MODEL_CARD::param_count() - 1 - i) { case 0: _tnom_c = value; break; default: CARD::set_param_by_index(i, value, offset); break; } } /*--------------------------------------------------------------------------*/ bool MODEL_CARD::param_is_printable(int i)const { switch (MODEL_CARD::param_count() - 1 - i) { case 0: return true; default: return CARD::param_is_printable(i); } } /*--------------------------------------------------------------------------*/ std::string MODEL_CARD::param_name(int i)const { switch (MODEL_CARD::param_count() - 1 - i) { case 0: return "tnom\0"; default: return CARD::param_name(i); } } /*--------------------------------------------------------------------------*/ std::string MODEL_CARD::param_name(int i, int j)const { if (j == 0) { return param_name(i); }else if (i >= CARD::param_count()) { return ""; }else{ return MODEL_CARD::param_name(i, j); } } /*--------------------------------------------------------------------------*/ std::string MODEL_CARD::param_value(int i)const { switch (MODEL_CARD::param_count() - 1 - i) { case 0: return _tnom_c.string(); default: return CARD::param_value(i); } } /*--------------------------------------------------------------------------*/ void MODEL_CARD::precalc_first() { CARD::precalc_first(); _tnom_c.e_val(OPT::tnom_c, scope()); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/e_model.h���������������������������������������������������������������������������������������0000664�0000000�0000000�00000005766�11454012162�0013434�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_model.h,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * base class for all models */ //testing=script 2007.07.13 #ifndef E_MODEL_H #define E_MODEL_H #include "u_parameter.h" #include "e_card.h" /*--------------------------------------------------------------------------*/ // external class COMPONENT; /*--------------------------------------------------------------------------*/ class SDP_CARD { private: explicit SDP_CARD() {unreachable();} explicit SDP_CARD(const SDP_CARD&) {unreachable();} public: explicit SDP_CARD(const COMMON_COMPONENT*) {} virtual ~SDP_CARD() {} virtual void init(const COMMON_COMPONENT*) {} }; /*--------------------------------------------------------------------------*/ class INTERFACE MODEL_CARD : public CARD{ protected: explicit MODEL_CARD(const MODEL_CARD& p); public: explicit MODEL_CARD(const COMPONENT* p); ~MODEL_CARD(); public: // override virtuals char id_letter()const {untested();return '\0';} CARD* clone_instance()const {itested(); assert(_component_proto); return _component_proto->clone();} void precalc_first(); void set_param_by_index(int, std::string&, int); bool param_is_printable(int)const; std::string value_name()const {return "";} std::string param_name(int)const; std::string param_name(int,int)const; std::string param_value(int)const; int param_count()const {return (1 + CARD::param_count());} public: virtual void tr_eval(COMPONENT*)const{unreachable();} virtual void ac_eval(COMPONENT*)const{unreachable();} virtual COMMON_COMPONENT* new_common()const {return 0;} virtual SDP_CARD* new_sdp(COMMON_COMPONENT*)const {unreachable();return 0;}; virtual bool parse_params_obsolete_callback(CS&) {unreachable(); return false;} virtual bool is_valid(const COMPONENT*)const {return true;} const CARD* component_proto()const {itested(); return _component_proto;} protected: const CARD* _component_proto; public: PARAMETER _tnom_c; }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ����������src/e_node.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000042677�11454012162�0013421�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_node.cc,v 26.132 2009/11/24 04:26:37 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * node probes */ //testing=script,sparse 2006.07.11 #include "u_nodemap.h" #include "d_logic.h" #include "e_aux.h" #include "u_xprobe.h" /*--------------------------------------------------------------------------*/ const _LOGICVAL LOGICVAL::or_truth[lvNUM_STATES][lvNUM_STATES] = { {lvSTABLE0, lvRISING, lvFALLING, lvSTABLE1, lvUNKNOWN}, {lvRISING, lvRISING, lvRISING, lvSTABLE1, lvRISING}, {lvFALLING, lvRISING, lvFALLING, lvSTABLE1, lvUNKNOWN}, {lvSTABLE1, lvSTABLE1, lvSTABLE1, lvSTABLE1, lvSTABLE1}, {lvUNKNOWN, lvRISING, lvUNKNOWN, lvSTABLE1, lvUNKNOWN} }; /*--------------------------------------------------------------------------*/ const _LOGICVAL LOGICVAL::xor_truth[lvNUM_STATES][lvNUM_STATES] = { {lvSTABLE0, lvRISING, lvFALLING, lvSTABLE1, lvUNKNOWN}, {lvRISING, lvFALLING, lvRISING, lvFALLING, lvUNKNOWN}, {lvFALLING, lvRISING, lvFALLING, lvRISING, lvUNKNOWN}, {lvSTABLE1, lvFALLING, lvRISING, lvSTABLE0, lvUNKNOWN}, {lvUNKNOWN, lvUNKNOWN, lvUNKNOWN, lvUNKNOWN, lvUNKNOWN} }; /*--------------------------------------------------------------------------*/ const _LOGICVAL LOGICVAL::and_truth[lvNUM_STATES][lvNUM_STATES] = { {lvSTABLE0, lvSTABLE0, lvSTABLE0, lvSTABLE0, lvSTABLE0}, {lvSTABLE0, lvRISING, lvFALLING, lvRISING, lvUNKNOWN}, {lvSTABLE0, lvFALLING, lvFALLING, lvFALLING, lvFALLING}, {lvSTABLE0, lvRISING, lvFALLING, lvSTABLE1, lvUNKNOWN}, {lvSTABLE0, lvUNKNOWN, lvFALLING, lvUNKNOWN, lvUNKNOWN} }; /*--------------------------------------------------------------------------*/ const _LOGICVAL LOGICVAL::not_truth[lvNUM_STATES] = { lvSTABLE1, lvFALLING, lvRISING, lvSTABLE0, lvUNKNOWN }; /*--------------------------------------------------------------------------*/ static _LOGICVAL prop_truth[lvNUM_STATES][lvNUM_STATES] = { {lvSTABLE0, lvUNKNOWN, lvUNKNOWN, lvRISING, lvUNKNOWN}, {lvUNKNOWN, lvUNKNOWN, lvUNKNOWN, lvUNKNOWN, lvUNKNOWN}, {lvUNKNOWN, lvUNKNOWN, lvUNKNOWN, lvUNKNOWN, lvUNKNOWN}, {lvFALLING, lvUNKNOWN, lvUNKNOWN, lvSTABLE1, lvUNKNOWN}, {lvFALLING, lvUNKNOWN, lvUNKNOWN, lvRISING, lvUNKNOWN} }; /*--------------------------------------------------------------------------*/ inline LOGICVAL& LOGICVAL::set_in_transition(LOGICVAL newval) { _lv = prop_truth[_lv][newval]; assert(_lv != lvUNKNOWN); return *this; } /*--------------------------------------------------------------------------*/ LOGIC_NODE::LOGIC_NODE() :NODE(), _family(0), _d_iter(0), _a_iter(0), _final_time(0), _lastchange(0), _old_lastchange(0), _mode(moANALOG), _lv(), _old_lv(), _quality(qBAD), _failure_mode("initial") { } /*--------------------------------------------------------------------------*/ /* default constructor : unconnected, don't use */ NODE::NODE() :CKT_BASE(), _user_number(INVALID_NODE) //_flat_number(INVALID_NODE) //_matrix_number(INVALID_NODE) { } /*--------------------------------------------------------------------------*/ /* copy constructor : user data only */ NODE::NODE(const NODE& p) :CKT_BASE(p), _user_number(p._user_number) //_flat_number(p._flat_number) //_matrix_number(INVALID_NODE) { unreachable(); } /*--------------------------------------------------------------------------*/ /* constructor taking a pointer : it must be valid * supposedly not used, but used by a required function that is also not used */ NODE::NODE(const NODE* p) :CKT_BASE(*p), _user_number(p->_user_number) //_flat_number(p->_flat_number) //_matrix_number(INVALID_NODE) { unreachable(); } /*--------------------------------------------------------------------------*/ /* usual initializing constructor : name and index */ NODE::NODE(const std::string& s, int n) :CKT_BASE(s), _user_number(n) //_flat_number(n) //_matrix_number(INVALID_NODE) { } /*--------------------------------------------------------------------------*/ node_t::node_t() :_nnn(0), _ttt(INVALID_NODE), _m(INVALID_NODE) { } node_t::node_t(const node_t& p) :_nnn(p._nnn), _ttt(p._ttt), _m(p._m) { //assert(_ttt == _nnn->flat_number()); } node_t::node_t(NODE* n) :_nnn(n), _ttt(n->user_number()), _m(to_internal(n->user_number())) { //assert(_ttt == _nnn->flat_number()); } node_t& node_t::operator=(const node_t& p) { if (p._nnn) { //assert(p._ttt == p._nnn->flat_number()); }else{ assert(p._ttt == INVALID_NODE); assert(p._m == INVALID_NODE); } _nnn = p._nnn; _ttt = p._ttt; _m = p._m; return *this; } /*--------------------------------------------------------------------------*/ LOGIC_NODE& node_t::data()const { assert(CKT_BASE::_sim->_nstat); return CKT_BASE::_sim->_nstat[m_()]; } /*--------------------------------------------------------------------------*/ double NODE::tr_probe_num(const std::string& x)const { if (Umatch(x, "v ")) { // return v0(); denoised return floor(v0()/OPT::vfloor + .5) * OPT::vfloor; }else if (Umatch(x, "z ")) { return port_impedance(node_t(const_cast(this)), node_t(&ground_node), _sim->_lu, 0.); }else if (Umatch(x, "l{ogic} |la{stchange} |fi{naltime} |di{ter} |ai{ter} |count ")) { assert(_sim->_nstat); return _sim->_nstat[matrix_number()].tr_probe_num(x); }else if (Umatch(x, "mdy ")) { // matrix diagonal admittance const BSMATRIX& aaa = _sim->_aa; return aaa.d(m_(),m_()); }else if (Umatch(x, "mdz ")) { // matrix diagonal impedance const BSMATRIX& aaa = _sim->_aa; return 1/aaa.d(m_(),m_()); }else if (Umatch(x, "zero ")) { // fake probe: 0.0 return 0.0; }else if (Umatch(x, "pdz ")) { // fake probe 1/0 .. positive divide by zero = Infinity double z1 = tr_probe_num("zero "); return 1.0/z1; }else if (Umatch(x, "ndz ")) { // fake probe -1/0 .. negative divide by zero = -Infinity double z1 = tr_probe_num("zero "); return -1.0/z1; }else if (Umatch(x, "nan ")) { // fake probe 0/0 = NaN double z1 = tr_probe_num("zero "); double z2 = tr_probe_num("zero "); return z1/z2; }else{itested(); return CKT_BASE::tr_probe_num(x); } } /*--------------------------------------------------------------------------*/ double LOGIC_NODE::tr_probe_num(const std::string& x)const { if (Umatch(x, "l{ogic} ")) { return annotated_logic_value(); }else if (Umatch(x, "la{stchange} ")) {untested(); return _lastchange; }else if (Umatch(x, "fi{naltime} ")) {untested(); return final_time(); }else if (Umatch(x, "di{ter} ")) {untested(); return static_cast(_d_iter); }else if (Umatch(x, "ai{ter} ")) {untested(); return static_cast(_a_iter); }else{ return NODE::tr_probe_num(x); } } /*--------------------------------------------------------------------------*/ XPROBE NODE::ac_probe_ext(const std::string& x)const { if (Umatch(x, "v ")) { return XPROBE(vac()); }else if (Umatch(x, "z ")) { return XPROBE(port_impedance(node_t(const_cast(this)), node_t(&ground_node), _sim->_acx, COMPLEX(0.))); }else{itested(); return CKT_BASE::ac_probe_ext(x); } } /*--------------------------------------------------------------------------*/ /* annotated_logic_value: a printable value for probe * that has secondary info encoded in its fraction part */ double LOGIC_NODE::annotated_logic_value()const { return (_lv + (.1 * (OPT::transits - quality())) + (.01 * (2 - _mode))); } /*--------------------------------------------------------------------------*/ static bool newly_stable[lvUNKNOWN+1][lvUNKNOWN+1] = { // oldlv, _lv /* s0 rise fall s1 u */ /* s0 */{false, false, false, true, false}, /*rise*/{false, false, false, true, false}, /*fall*/{true, false, false, false, false}, /* s1 */{true, false, false, false, false}, /* u */{true, false, false, true, false} }; /*--------------------------------------------------------------------------*/ inline bool LOGIC_NODE::just_reached_stable()const { return newly_stable[old_lv()][lv()]; } /*--------------------------------------------------------------------------*/ /* to_logic: set up logic data for a node, if needed * If the logic data is already up to date, do nothing. * else set up: logic value (_lv) and quality. * Use and update _d_iter, _lastchange to keep track of what was done. */ void LOGIC_NODE::to_logic(const MODEL_LOGIC*f) { assert(f); if (process() && process() != f) {untested(); set_bad_quality("logic process mismatch"); error(bWARNING, "node " + long_label() + " logic process mismatch\nis it " + process()->long_label() + " or " + f->long_label() + "?\n"); } set_process(f); if (is_analog() && d_iter() < a_iter()) { if (_sim->analysis_is_restore()) {untested(); }else if (_sim->analysis_is_static()) { }else{ } if (_sim->analysis_is_static() || _sim->analysis_is_restore()) { set_last_change_time(0); store_old_last_change_time(); set_lv(lvUNKNOWN); }else{ } double dt = _sim->_time0 - last_change_time(); if (dt < 0.) {untested(); error(bPICKY, "time moving backwards. was %g, now %g\n", last_change_time(), _sim->_time0); dt = _sim->_time0 - old_last_change_time(); if (dt <= 0.) {untested(); throw Exception("internal error: time moving backwards, can't recover"); }else{untested(); } assert(dt > 0.); restore_lv(); /* skip back one */ }else{ store_old_last_change_time(); store_old_lv(); /* save to see if it changes */ } double sv = v0() / process()->range; /* new scaled voltage */ if (sv >= process()->th1) { /* logic 1 */ switch (lv()) { case lvSTABLE0: dont_set_quality("stable 0 to stable 1"); break; case lvRISING: dont_set_quality("begin stable 1"); break; case lvFALLING:untested();set_bad_quality("falling to stable 1"); break; case lvSTABLE1: dont_set_quality("continuing stable 1"); break; case lvUNKNOWN: set_good_quality("initial 1"); break; } set_lv(lvSTABLE1); }else if (sv <= process()->th0) { /* logic 0 */ switch (lv()) { case lvSTABLE0: dont_set_quality("continuing stable 0"); break; case lvRISING: untested();set_bad_quality("rising to stable 0"); break; case lvFALLING: dont_set_quality("begin stable 0"); break; case lvSTABLE1: dont_set_quality("stable 1 to stable 0"); break; case lvUNKNOWN: set_good_quality("initial 0"); break; } set_lv(lvSTABLE0); }else{ /* transition region */ double oldsv = vt1() / process()->range;/* old scaled voltage */ double diff = sv - oldsv; if (diff > 0) { /* rising */ switch (lv()) { case lvSTABLE0: dont_set_quality("begin good rise"); break; case lvRISING: if (diff < dt/(process()->mr * process()->rise)) { set_bad_quality("slow rise"); }else{ dont_set_quality("continuing good rise"); } break; case lvFALLING: untested(); set_bad_quality("positive glitch in fall"); break; case lvSTABLE1: untested(); set_bad_quality("negative glitch in 1"); break; case lvUNKNOWN: set_bad_quality("initial rise"); break; } set_lv(lvRISING); }else if (diff < 0) { /* falling */ switch (lv()) { case lvSTABLE0: untested(); set_bad_quality("positive glitch in 0"); break; case lvRISING: set_bad_quality("negative glitch in rise"); break; case lvFALLING: if (-diff < dt/(process()->mf * process()->fall)) { set_bad_quality("slow fall"); }else{ dont_set_quality("continuing good fall"); } break; case lvSTABLE1: dont_set_quality("begin good fall"); break; case lvUNKNOWN: untested(); set_bad_quality("initial fall"); break; } set_lv(lvFALLING); }else{ /* hanging up in transition */ untested(); error(bDANGER, "inflection???\n"); set_bad_quality("in transition but no change"); /* state (rise/fall) unchanged */ } } if (sv > 1.+process()->over || sv < -process()->over) {/* out of range */ set_bad_quality("out of range"); } if (just_reached_stable()) { /* A bad node gets a little better */ improve_quality(); /* on every good transition. */ } /* Eventually, it is good enough. */ /* A good transition is defined as */ /* entering a stable state from */ /* a transition state. */ set_d_iter(); set_last_change_time(); trace3(_failure_mode, _lastchange, _quality, _lv); } } /*--------------------------------------------------------------------------*/ double LOGIC_NODE::to_analog(const MODEL_LOGIC* f) { assert(f); if (process() && process() != f) {untested(); error(bWARNING, "node " + long_label() + " logic process mismatch\nis it " + process()->long_label() + " or " + f->long_label() + "?\n"); } set_process(f); double start = NOT_VALID; double end = NOT_VALID; double risefall = NOT_VALID; switch (lv()) { case lvSTABLE0: return process()->vmin; case lvRISING: untested(); start = process()->vmin; end = process()->vmax; risefall = process()->rise; break; case lvFALLING: start = process()->vmax; end = process()->vmin; risefall = process()->fall; break; case lvSTABLE1: return process()->vmax; case lvUNKNOWN: return process()->unknown; } assert(start != NOT_VALID); assert(end != NOT_VALID); assert(risefall != NOT_VALID); if (_sim->_time0 <= (final_time()-risefall)) { return start; }else if (_sim->_time0 >= final_time()) { untested(); return end; }else{ untested(); return end - ((end-start) * (final_time()-_sim->_time0) / risefall); } } /*--------------------------------------------------------------------------*/ void LOGIC_NODE::propagate() { assert(in_transit()); if (lv().is_rising()) { set_lv(lvSTABLE1); }else if (lv().is_falling()) { set_lv(lvSTABLE0); }else{ // lv no change } set_d_iter(); set_final_time(NEVER); set_last_change_time(); assert(!(in_transit())); } /*--------------------------------------------------------------------------*/ void LOGIC_NODE::force_initial_value(LOGICVAL v) { if (_sim->analysis_is_restore()) {untested(); }else if (_sim->analysis_is_static()) { }else{untested(); } assert(_sim->analysis_is_static() || _sim->analysis_is_restore()); assert(_sim->_time0 == 0.); assert(is_unknown()); assert(is_digital()); set_lv(v); // BUG ?? set_good_quality("initial dc"); set_d_iter(); set_final_time(NEVER); set_last_change_time(); } /*--------------------------------------------------------------------------*/ void LOGIC_NODE::set_event(double delay, LOGICVAL v) { _lv.set_in_transition(v); if (_sim->analysis_is_tran_dynamic() && in_transit()) {untested(); set_bad_quality("race"); } set_d_iter(); set_final_time(_sim->_time0 + delay); if (OPT::picky <= bTRACE) {untested(); error(bTRACE, "%s:%u:%g new event\n", long_label().c_str(), d_iter(), final_time()); } set_last_change_time(); } /*--------------------------------------------------------------------------*/ void node_t::set_to_ground(CARD* d) { //assert(!_nnn); //BUG// fails on MUTUAL_L::expand after clone assert(d); NODE_MAP* Map = d->scope()->nodes(); assert(Map); _nnn = (*Map)["0"]; _ttt = 0; assert(_nnn); } /*--------------------------------------------------------------------------*/ /* new_node: a raw new node, as when a netlist is parsed */ void node_t::new_node(const std::string& node_name, const CARD* d) { //assert(!_nnn); //BUG// fails on MUTUAL_L::expand after clone assert(d); NODE_MAP* Map = d->scope()->nodes(); assert(Map); _nnn = Map->new_node(node_name); _ttt = _nnn->user_number(); assert(_nnn); } /*--------------------------------------------------------------------------*/ /* new_model_node: a mapped new node, produced through model expansion. * Not really a model_node, but a node in the subckt that is made * in model expansion. * Supposedly equivalent to new_node() then map_subckt_node() * but it does it without building a map */ void node_t::new_model_node(const std::string& node_name, CARD* d) { new_node(node_name, d); _ttt = CKT_BASE::_sim->newnode_model(); //assert(_ttt == _nnn->flat_number()); } /*--------------------------------------------------------------------------*/ void node_t::map_subckt_node(int* m, const CARD* d) { assert(m); assert(e_() >= 0); if (node_is_valid(m[e_()])) { _ttt = m[e_()]; }else{untested(); throw Exception(d->long_label() + ": need more nodes"); } //_nnn->set_flat_number(_ttt); assert(node_is_valid(_ttt)); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������src/e_node.h����������������������������������������������������������������������������������������0000664�0000000�0000000�00000027012�11454012162�0013245�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_node.h,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * circuit node class */ //testing=script,sparse 2006.07.11 #ifndef E_NODE_H #define E_NODE_H #include "u_sim_data.h" #include "e_base.h" /*--------------------------------------------------------------------------*/ class MODEL_LOGIC; /*--------------------------------------------------------------------------*/ enum { OUT1 = 0, OUT2 = 1, IN1 = 2, IN2 = 3, NODES_PER_BRANCH = 4, INVALID_NODE = -1 }; #define qBAD (0) #define qGOOD (OPT::transits) /*--------------------------------------------------------------------------*/ enum _LOGICVAL {lvSTABLE0,lvRISING,lvFALLING,lvSTABLE1,lvUNKNOWN}; enum {lvNUM_STATES = lvUNKNOWN+1}; /*--------------------------------------------------------------------------*/ class INTERFACE LOGICVAL { private: _LOGICVAL _lv; static const _LOGICVAL or_truth[lvNUM_STATES][lvNUM_STATES]; static const _LOGICVAL xor_truth[lvNUM_STATES][lvNUM_STATES]; static const _LOGICVAL and_truth[lvNUM_STATES][lvNUM_STATES]; static const _LOGICVAL not_truth[lvNUM_STATES]; public: LOGICVAL() :_lv(lvUNKNOWN) {} LOGICVAL(const LOGICVAL& p) :_lv(p._lv) {} LOGICVAL(_LOGICVAL p) :_lv(p) {} ~LOGICVAL() {} operator _LOGICVAL()const {return static_cast<_LOGICVAL>(_lv);} LOGICVAL& operator=(_LOGICVAL p) {_lv=p; return *this;} LOGICVAL& operator=(const LOGICVAL& p) {_lv=p._lv; return *this;} LOGICVAL& operator&=(LOGICVAL p) {untested(); _lv = and_truth[_lv][p._lv]; return *this;} LOGICVAL& operator|=(LOGICVAL p) {_lv = or_truth[_lv][p._lv]; return *this;} LOGICVAL operator^=(LOGICVAL p) {untested(); _lv = xor_truth[_lv][p._lv]; return *this;} LOGICVAL operator~()const {return not_truth[_lv];} bool is_unknown()const {return _lv == lvUNKNOWN;} bool lv_future()const {assert(_lv!=lvUNKNOWN); return _lv & 1;} bool lv_old()const {assert(_lv!=lvUNKNOWN); return _lv & 2;} bool is_rising() const {return _lv == lvRISING;} bool is_falling()const {return _lv == lvFALLING;} LOGICVAL& set_in_transition(LOGICVAL newval); }; /*--------------------------------------------------------------------------*/ class NODE : public CKT_BASE { private: int _user_number; //int _flat_number; //int _matrix_number; protected: explicit NODE(); private: // inhibited explicit NODE(const NODE& p); public: explicit NODE(const NODE* p); // u_nodemap.cc:49 (deep copy) explicit NODE(const std::string& s, int n); ~NODE() {} public: // raw data access (rvalues) int user_number()const {return _user_number;} //int flat_number()const {itested();return _flat_number;} public: // simple calculated data access (rvalues) int matrix_number()const {return _sim->_nm[_user_number];} int m_()const {return matrix_number();} public: // maniputation NODE& set_user_number(int n) {_user_number = n; return *this;} //NODE& set_flat_number(int n) {itested();_flat_number = n; return *this;} //NODE& set_matrix_number(int n){untested();_matrix_number = n;return *this;} public: // virtuals double tr_probe_num(const std::string&)const; XPROBE ac_probe_ext(const std::string&)const; double v0()const { assert(m_() >= 0); assert(m_() <= _sim->_total_nodes); return _sim->_v0[m_()]; } double vt1()const { assert(m_() >= 0); assert(m_() <= _sim->_total_nodes); return _sim->_vt1[m_()]; } COMPLEX vac()const { assert(m_() >= 0); assert(m_() <= _sim->_total_nodes); return _sim->_ac[m_()]; } //double vdc()const {untested();return _vdc[m_()];} //double& i() {untested();return _i[m_()];} /* lvalues */ COMPLEX& iac() { assert(m_() >= 0); assert(m_() <= _sim->_total_nodes); return _sim->_ac[m_()]; } }; extern NODE ground_node; /*--------------------------------------------------------------------------*/ class INTERFACE LOGIC_NODE : public NODE { private: const MODEL_LOGIC *_family; /* logic family */ int _d_iter; /* iteration of last update - digital */ int _a_iter; /* iteration of last update - analog */ double _final_time; /* time logic transition attains final state */ double _lastchange; /* time of last change */ double _old_lastchange; /* in case it rejects a step */ smode_t _mode; /* simulation mode (analog or digital)*/ LOGICVAL _lv; /* "logic value" (real type is LOGICVAL) */ LOGICVAL _old_lv; /* in case it rejects a step */ int _quality; /* quality of digital mode */ std::string _failure_mode; // so it is not pure virtual //const std::string long_label()const; public: // virtuals double tr_probe_num(const std::string&)const; //XPROBE ac_probe_ext(const std::string&)const; public: // raw data access (rvalues) LOGICVAL lv()const {return _lv;} int quality()const {return _quality;} const std::string& failure_mode()const {return _failure_mode;} int d_iter()const {return _d_iter;} int a_iter()const {return _a_iter;} double final_time()const {return _final_time;} double last_change_time()const {return _lastchange;} const MODEL_LOGIC* process()const {return _family;} double old_last_change_time()const {untested(); return _old_lastchange;} const LOGICVAL old_lv()const {return _old_lv;} public: // simple calculated data access (rvalues) bool lv_future()const {return lv().lv_future();} bool is_unknown()const {return lv().is_unknown();} bool in_transit()const {return final_time() < NEVER;} bool is_digital()const {return _mode == moDIGITAL;} bool is_analog()const {return _mode == moANALOG;} double annotated_logic_value()const; public: // calculated data access (rvalues) bool just_reached_stable()const; public: // raw data access (lvalues) void set_quality(int q) {_quality = q;} void set_failure_mode(const std::string& f) {_failure_mode = f;} void set_final_time(double t) {_final_time = t;} void set_d_iter() {_d_iter = _sim->iteration_tag();} void set_last_change_time() {_lastchange = _sim->_time0;} void set_last_change_time(double t) {_lastchange = t;} void set_lv(LOGICVAL v) {_lv = v;} void set_process(const MODEL_LOGIC* f) {_family = f;} void store_old_last_change_time() {_old_lastchange = last_change_time();} void store_old_lv() {_old_lv = lv();} void restore_lv() {untested(); set_lv(old_lv());} void set_mode(smode_t m) {_mode = m;} public: // other internal void set_bad_quality(const std::string& f) { set_quality(qBAD); set_failure_mode(f); } void set_good_quality(const std::string& f = "ok") { set_quality(qGOOD); set_failure_mode(f); } void dont_set_quality(const std::string& f = "don't know") { set_failure_mode(f); } void improve_quality() { if (quality() < qGOOD) { ++_quality; } } public: // action, used by logic void set_event(double delay, LOGICVAL v); void force_initial_value(LOGICVAL v); void propagate(); double to_analog(const MODEL_LOGIC*f); void to_logic(const MODEL_LOGIC*f); private: // inhibited explicit LOGIC_NODE(const LOGIC_NODE&):NODE(){incomplete();unreachable();} public: // general use explicit LOGIC_NODE(); ~LOGIC_NODE() {} public: // matrix LOGIC_NODE& set_a_iter() {_a_iter = _sim->iteration_tag(); return *this;} }; /*--------------------------------------------------------------------------*/ class INTERFACE node_t { private: static bool node_is_valid(int i) { if (i == INVALID_NODE) {untested(); itested(); }else if (i < 0) { unreachable(); }else if (i > NODE::_sim->_total_nodes) { unreachable(); }else{ } return i>=0 && i<=NODE::_sim->_total_nodes; } static int to_internal(int n) { assert(node_is_valid(n)); assert(NODE::_sim->_nm); return NODE::_sim->_nm[n]; } private: NODE* _nnn; int _ttt; // m == nm[t] if properly set up int _m; // mapped, after reordering public: int m_()const {return _m;} int t_()const { //assert(_nnn); //assert(_ttt == _nnn->flat_number()); return _ttt; } // e_cardlist.cc:CARD_LIST::map_subckt_nodes:436 and // e_node.h:node_t::map:263,265 only int e_()const { assert(_nnn); return ((_nnn) ? _nnn->user_number() : INVALID_NODE); } const NODE* n_()const {return _nnn;} NODE* n_() {return _nnn;} const std::string short_label()const {return ((n_()) ? (n_()->short_label()) : "?????");} void set_to_ground(CARD*); void new_node(const std::string&, const CARD*); void new_model_node(const std::string& n, CARD* d); void map_subckt_node(int* map_array, const CARD* d); bool is_grounded()const {return (e_() == 0);} bool is_connected()const {return (e_() != INVALID_NODE);} node_t& map() { if (t_() != INVALID_NODE) { assert(_nnn); _m=to_internal(t_()); }else{ assert(_m == INVALID_NODE); } return *this; } // e_compon.cc:COMPONENT::map_nodes:522 explicit node_t(); node_t(const node_t&); explicit node_t(NODE*); ~node_t() {} private: // raw data access (lvalues) LOGIC_NODE& data()const; public: //LOGIC_NODE& operator*()const {untested();return data();} const LOGIC_NODE* operator->()const {return &data();} LOGIC_NODE* operator->() {return &data();} node_t& operator=(const node_t& p); bool operator==(const node_t& p) {return _nnn==p._nnn && _ttt==p._ttt && _m==p._m;} public: double v0()const { //assert(m_() >= 0); if (m_() >= 0) { assert(m_() <= NODE::_sim->_total_nodes); assert(n_()); //assert(n_()->m_() == m_()); //assert(n_()->v0() == NODE::_sim->_v0[m_()]); return NODE::_sim->_v0[m_()]; }else{ //BUG// in BJT model: should not get here but does. return 0.; } } COMPLEX vac()const { //assert(m_() >= 0); if (m_() >= 0) { assert(m_() <= NODE::_sim->_total_nodes); assert(n_()); //assert(n_()->m_() == m_()); //assert(n_()->vac() == NODE::_ac[m_()]); return NODE::_sim->_ac[m_()]; }else{untested(); //BUG// assume v0 BUG applies here too. return 0.; } } double& i() { assert(m_() >= 0); assert(m_() <= NODE::_sim->_total_nodes); return NODE::_sim->_i[m_()]; } #if 0 COMPLEX& iac() {untested(); assert(n_()); assert(n_()->m_() == m_()); assert(n_()->iac() == NODE::_ac[m_()]); //return n_()->iac(); return NODE::_sim->_ac[m_()]; } #endif }; /*--------------------------------------------------------------------------*/ INTERFACE double volts_limited(const node_t& n1, const node_t& n2); /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/e_storag.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000017014�11454012162�0013756�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_storag.cc,v 26.132 2009/11/24 04:26:37 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Base class for storage elements of a circuit */ //testing=obsolete,script 2006.06.14 #include "e_storag.h" /*--------------------------------------------------------------------------*/ /* table for selecting local integraton method * Determines which one wins in a conflict. * "only" wins over non-only. local (_method_u) wins over opt. */ // OPT::method _method_u METHOD STORAGE::method_select[meNUM_METHODS][meNUM_METHODS] = { /*vv OPT vv*/ //local>>>EULER,EULERONLY,TRAP,TRAPONLY,GEAR2,GEAR2ONLY,TRAPGEAR,TRAPEULER /*meUNKNOWN*/ {mTRAPGEAR,mEULER,mEULER,mTRAP, mTRAP,mGEAR, mGEAR,mTRAPGEAR,mTRAPEULER}, /*meEULER*/ {mEULER, mEULER,mEULER,mTRAP, mTRAP,mGEAR, mGEAR,mTRAPGEAR,mTRAPEULER}, /*meEULERONLY*/ {mEULER, mEULER,mEULER,mEULER,mTRAP,mEULER,mGEAR,mEULER, mEULER}, /*meTRAP*/ {mTRAP, mEULER,mEULER,mTRAP, mTRAP,mGEAR, mGEAR,mTRAPGEAR,mTRAPEULER}, /*meTRAPONLY*/ {mTRAP, mTRAP, mEULER,mTRAP, mTRAP,mTRAP, mGEAR,mTRAP, mTRAP}, /*meGEAR*/ {mGEAR, mEULER,mEULER,mTRAP, mTRAP,mGEAR, mGEAR,mTRAPGEAR,mTRAPEULER}, /*meGEAR2ONLY*/ {mGEAR, mGEAR, mEULER,mGEAR, mTRAP,mGEAR, mGEAR,mGEAR, mGEAR}, /*meTRAPGEAR*/ {mTRAPGEAR,mEULER,mEULER,mTRAP, mTRAP,mGEAR, mGEAR,mTRAPGEAR,mTRAPEULER}, /*meTRAPEULER*/ {mTRAPEULER,mEULER,mEULER,mTRAP,mTRAP,mGEAR, mGEAR,mTRAPGEAR,mTRAPEULER} }; /*--------------------------------------------------------------------------*/ void STORAGE::precalc_last() { ELEMENT::precalc_last(); set_converged(); assert(!is_constant()); /* because of integration */ _method_a = method_select[OPT::method][_method_u]; //assert(_loss0 == 0.); //assert(_loss1 == 0.); /* m0 and acg are frequency/time dependent and cannot be set here. * If this is a coupled inductor, there is a subckt, which is expanded * by the mutual pseudo-element. * Assigning the values here becomes unnecessary, but harmless. */ } /*--------------------------------------------------------------------------*/ void STORAGE::tr_begin() { ELEMENT::tr_begin(); _method_a = method_select[OPT::method][_method_u]; for (int i = 0; i < OPT::_keep_time_steps; ++i) { _i[i] = FPOLY1(0., 0., 0.); } _m1 = _m0 = CPOLY1(0., 0., 0.); } /*--------------------------------------------------------------------------*/ void STORAGE::tr_restore() { ELEMENT::tr_restore(); _method_a = method_select[OPT::method][_method_u]; } /*--------------------------------------------------------------------------*/ void STORAGE::dc_advance() { ELEMENT::dc_advance(); for (int i = 1; i < OPT::_keep_time_steps; ++i) { _i[i] = _i[0]; } } /*--------------------------------------------------------------------------*/ void STORAGE::tr_advance() { ELEMENT::tr_advance(); for (int i=OPT::_keep_time_steps-1; i>0; --i) { _i[i] = _i[i-1]; } } /*--------------------------------------------------------------------------*/ /* tr_needs_eval: check to see if this device needs to be evaluated * this works, and saves significant time * but possible errors. * Errors do not seem significant, but I can't tell without more data. * To disable: option nolcbypass */ bool STORAGE::tr_needs_eval()const { //assert(!is_q_for_eval()); return (!OPT::lcbypass || !converged() || _sim->is_advance_or_first_iteration() || !conchk(_y[0].x, tr_input(), OPT::abstol) || _sim->uic_now()); } /*--------------------------------------------------------------------------*/ /* differentiate: this is what Spice calls "integrate". * returns an approximation of the time derivative of _q, * where _q is an array of states .. charge for capacitors, flux for inductors. * return value is current for capacitors, volts for inductors. */ FPOLY1 differentiate(const FPOLY1* q, const FPOLY1* i, double* time, METHOD method) { if (CKT_BASE::_sim->analysis_is_static()) { assert(time[0] == 0.); return FPOLY1(q[0].x, 0., 0.); }else if (CKT_BASE::_sim->analysis_is_restore()) { /* leave it alone to restart from a previous solution */ /* it goes this way to continue a transient analysis */ assert(time[0] > 0); return i[0]; }else{ assert(CKT_BASE::_sim->analysis_is_tran_dynamic()); if (time[1] == 0) { method = mEULER; // Bogus current in previous step. Force Euler. }else{ } double dt = time[0] - time[1]; assert(dt > 0.); switch (method) { case mTRAPGEAR: incomplete(); case mGEAR: assert(OPT::_keep_time_steps >= 3); return FPOLY1(q[0].x, (3./2.) * (q[0].f0 - q[1].f0) / dt - (1./2.) * (q[1].f0 - q[2].f0) / (time[1] - time[2]), q[0].f1 * (3./2.) / dt); case mTRAPEULER: incomplete(); case mEULER: assert(OPT::_keep_time_steps >= 2); return FPOLY1(q[0].x, (q[0].f0 - q[1].f0) / dt, q[0].f1 / dt); case mTRAP: assert(OPT::_keep_time_steps >= 2); return FPOLY1(q[0].x, 2 * (q[0].f0 - q[1].f0) / dt - i[1].f0, q[0].f1 * 2 / dt); } unreachable(); return FPOLY1(); } unreachable(); } /*--------------------------------------------------------------------------*/ double STORAGE::tr_c_to_g(double c, double g)const { if (_sim->analysis_is_static()) { assert(_time[0] == 0.); return 0.; }else if (_sim->analysis_is_restore()) {itested(); assert(_time[0] > 0); return g; // no change, fake }else{ assert(_sim->analysis_is_tran_dynamic()); METHOD method; if (_time[1] == 0) { method = mEULER; // Bogus current in previous step. Force Euler. }else{ method = _method_a; } g = c / _dt; switch (method) { case mTRAPGEAR: incomplete(); case mGEAR: g *= 3./2.; break; case mTRAPEULER: incomplete(); case mEULER: /* g *= 1 */ break; case mTRAP: g *= 2; break; } return g; } } /*--------------------------------------------------------------------------*/ TIME_PAIR STORAGE::tr_review() { COMPONENT::tr_review(); // skip ELEMENT if (_method_a == mEULER) { // Backward Euler, no step control, take it as it comes }else{ double timestep = tr_review_trunc_error(_y); _time_by.min_error_estimate(tr_review_check_and_convert(timestep)); } return _time_by; } /*--------------------------------------------------------------------------*/ double STORAGE::tr_probe_num(const std::string& x)const { if (Umatch(x, "method ")) {untested(); return static_cast(_method_a); }else{ return ELEMENT::tr_probe_num(x); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/e_storag.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000005706�11454012162�0013625�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_storag.h,v 26.127 2009/11/09 16:06:11 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * "base" class for energy storage elements (L & C) */ //testing=script,complete 2007.07.13 #ifndef E_STORAGE_H #define E_STORAGE_H #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ enum METHOD {mTRAPGEAR, mEULER, mTRAP, mGEAR, mTRAPEULER}; /*--------------------------------------------------------------------------*/ INTERFACE FPOLY1 differentiate(const FPOLY1* q, const FPOLY1* i, double* time, METHOD method); /*--------------------------------------------------------------------------*/ class INTERFACE STORAGE : public ELEMENT { private: protected: explicit STORAGE() :ELEMENT(), _method_u(meUNKNOWN), _method_a(mTRAPGEAR) {} explicit STORAGE(const STORAGE& p) :ELEMENT(p), _method_u(p._method_u), _method_a(p._method_a) {} ~STORAGE() {} public: // override virtual //void precalc_first(); //ELEMENT //void expand(); //COMPONENT void precalc_last(); void tr_begin(); void tr_restore(); void dc_advance(); void tr_advance(); //void tr_regress(); //ELEMENT bool tr_needs_eval()const; //void tr_queue_eval() //ELEMENT TIME_PAIR tr_review(); double tr_probe_num(const std::string&)const; public: double tr_c_to_g(double c, double g)const; private: int order()const { const int o[] = {1, 1, 2, 1, 1}; int ord = o[_method_a]; assert(ord < OPT::_keep_time_steps); return ord; } double error_factor()const { const double f[]={1./2., 1./2., 1./12., 1./6., 1./2.}; return f[_method_a]; } public: // used by commons method_t _method_u; /* method to use for this part per user */ METHOD _method_a; /* actual integration method (auto) */ protected: FPOLY1 _i[OPT::_keep_time_steps]; /* deriv of _q */ protected: static METHOD method_select[meNUM_METHODS][meNUM_METHODS]; }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ����������������������������������������������������������src/e_subckt.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000006232�11454012162�0013614�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: e_subckt.h,v 26.126 2009/10/16 05:29:28 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * base class for elements made of subcircuits */ //testing=script 2006.07.12 #ifndef E_SUBCKT_H #define E_SUBCKT_H #include "e_compon.h" /*--------------------------------------------------------------------------*/ class BASE_SUBCKT : public COMPONENT { protected: explicit BASE_SUBCKT() :COMPONENT() {} explicit BASE_SUBCKT(const BASE_SUBCKT& p) :COMPONENT(p) {} ~BASE_SUBCKT() {} protected: // override virtual //char id_letter()const //CARD/null std::string dev_type()const {assert(common()); return common()->modelname();} int tail_size()const {return 1;} //int max_nodes()const //COMPONENT/null //int num_nodes()const //COMPONENT/null //int min_nodes()const //COMPONENT/null int matrix_nodes()const {return 0;} int net_nodes()const {return _net_nodes;} //CARD* clone()const //CARD/null //void precalc_first() {assert(subckt()); subckt()->precalc();} //void expand() //COMPONENT //void precalc_last() {assert(subckt()); subckt()->precalc();} //void map_nodes(); void tr_begin() {assert(subckt()); subckt()->tr_begin();} void tr_restore() {assert(subckt()); subckt()->tr_restore();} void dc_advance() {assert(subckt()); subckt()->dc_advance();} void tr_advance() {assert(subckt()); subckt()->tr_advance();} void tr_regress() {assert(subckt()); subckt()->tr_regress();} bool tr_needs_eval()const {assert(subckt()); return subckt()->tr_needs_eval();} void tr_queue_eval() {assert(subckt()); subckt()->tr_queue_eval();} bool do_tr() {assert(subckt());set_converged(subckt()->do_tr());return converged();} void tr_load() {assert(subckt()); subckt()->tr_load();} TIME_PAIR tr_review() {assert(subckt()); return _time_by = subckt()->tr_review();} void tr_accept() {assert(subckt()); subckt()->tr_accept();} void tr_unload() {assert(subckt()); subckt()->tr_unload();} void ac_begin() {assert(subckt()); subckt()->ac_begin();} void do_ac() {assert(subckt()); subckt()->do_ac();} void ac_load() {assert(subckt()); subckt()->ac_load();} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/findbr.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000007121�11454012162�0013415�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: findbr.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * find a branch with matching label * returns the branch pointer */ //testing=script,sparse 2006.07.17 #include "l_lib.h" #include "constant.h" #include "e_cardlist.h" #include "ap.h" #include "e_card.h" /*--------------------------------------------------------------------------*/ /* findbranch: find a matching label, by (ugh) linear search * label to look for is in command line (cmd). * start "here". Look only after "here". * return pointer to next match if exists (and eat input) * pointer to a non-existent branch if no match (don't eat input) * caution: caller must check return value before using */ CARD_LIST::fat_iterator findbranch(CS& cmd, CARD_LIST::fat_iterator here) { unsigned save = cmd.cursor(); char labelwanted[BUFLEN+1]; cmd.ctostr(labelwanted, BUFLEN, TOKENTERM); if (!labelwanted[0]) { // nothing to look for cmd.reset(save); return here.end(); }else{ } char* local_part; // part before last dot, the thing inside char* last_part; // part after last dot, top level { char* dot = strrchr(labelwanted,'.'); if (dot) {itested(); // split the string into 2 parts at the last dot *dot = '\0'; // before is the new "local_part", shortened last_part = dot + 1; // after is the "last_part". local_part = labelwanted; }else{ last_part = labelwanted; local_part = NULL; } } for (;;) { if (here.is_end()) { // at the end of the list - done, fails. cmd.reset(save); return here; }else if (wmatch((**here).short_label(), last_part)) { // last_part matches if (!local_part) { // requested a simple name, found it .. done. return here; }else{untested(); // there are dots, so look inside subckt untested(); if ((**here).subckt()) {untested(); untested(); // has a subckt, and its name matches, doing fine CS want(CS::_STRING, local_part); // recursion CARD_LIST::fat_iterator subbrh=findbranch(want,(**here).subckt()); if (!subbrh.is_end()) {untested(); // found it in a subckt return subbrh; }else{untested(); // didn't find anything in this subckt // keep looking for another with the same name // why? ++here; } }else{untested(); // no subckt // keep looking for something with this name that has a subckt // why? untested(); ++here; } } }else{ // label doesn't match // keep looking for one that does. (linear search) ++here; } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/func_core.cc������������������������������������������������������������������������������������0000664�0000000�0000000�00000020460�11454012162�0014115�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: func_core.cc,v 26.127 2009/11/09 16:06:11 al Exp $ -*- C++ -*- * Copyright (C) 2008 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ #include "u_parameter.h" #include "u_function.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class abs : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER x; Cmd >> x; x.e_val(NOT_INPUT, Scope); return to_string(std::abs(x)); } } p_abs; DISPATCHER::INSTALL d_abs(&function_dispatcher, "abs", &p_abs); /*--------------------------------------------------------------------------*/ class sqrt : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER x; Cmd >> x; x.e_val(NOT_INPUT, Scope); return to_string(std::sqrt(x)); } } p_sqrt; DISPATCHER::INSTALL d_sqrt(&function_dispatcher, "sqrt", &p_sqrt); /*--------------------------------------------------------------------------*/ class log : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER x; Cmd >> x; x.e_val(NOT_INPUT, Scope); return to_string(std::log(x)); } } p_log; DISPATCHER::INSTALL d_log(&function_dispatcher, "log", &p_log); /*--------------------------------------------------------------------------*/ class exp : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER x; Cmd >> x; x.e_val(NOT_INPUT, Scope); return to_string(std::exp(x)); } } p_exp; DISPATCHER::INSTALL d_exp(&function_dispatcher, "exp", &p_exp); /*--------------------------------------------------------------------------*/ class INT : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER x; Cmd >> x; x.e_val(NOT_INPUT, Scope); return to_string(std::floor(x)); } } p_int; DISPATCHER::INSTALL d_int(&function_dispatcher, "int", &p_int); /*--------------------------------------------------------------------------*/ class pow : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER x, y; Cmd >> x >> y; x.e_val(NOT_INPUT, Scope); y.e_val(NOT_INPUT, Scope); return to_string(std::pow(x,y)); } } p_pow; DISPATCHER::INSTALL d_pow(&function_dispatcher, "pow", &p_pow); /*--------------------------------------------------------------------------*/ class MAX : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER x, y; Cmd >> x >> y; x.e_val(NOT_INPUT, Scope); y.e_val(NOT_INPUT, Scope); return to_string(std::max(x,y)); } } p_max; DISPATCHER::INSTALL d_max(&function_dispatcher, "max", &p_max); /*--------------------------------------------------------------------------*/ class MIN : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER x, y; Cmd >> x >> y; x.e_val(NOT_INPUT, Scope); y.e_val(NOT_INPUT, Scope); return to_string(std::min(x,y)); } } p_min; DISPATCHER::INSTALL d_min(&function_dispatcher, "min", &p_min); /*--------------------------------------------------------------------------*/ class IF : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER x, y, z; Cmd >> x >> y; x.e_val(NOT_INPUT, Scope); y.e_val(NOT_INPUT, Scope); z.e_val(NOT_INPUT, Scope); return to_string(x ? y : z); } } p_if; DISPATCHER::INSTALL d_if(&function_dispatcher, "if", &p_if); /*--------------------------------------------------------------------------*/ class sin : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER x; Cmd >> x; x.e_val(NOT_INPUT, Scope); return to_string(std::sin(x)); } } p_sin; DISPATCHER::INSTALL d_sin(&function_dispatcher, "sin", &p_sin); /*--------------------------------------------------------------------------*/ class sinh : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER x; Cmd >> x; x.e_val(NOT_INPUT, Scope); return to_string(std::sinh(x)); } } p_sinh; DISPATCHER::INSTALL d_sinh(&function_dispatcher, "sinh", &p_sinh); /*--------------------------------------------------------------------------*/ class cos : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER x; Cmd >> x; x.e_val(NOT_INPUT, Scope); return to_string(std::cos(x)); } } p_cos; DISPATCHER::INSTALL d_cos(&function_dispatcher, "cos", &p_cos); /*--------------------------------------------------------------------------*/ class cosh : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER x; Cmd >> x; x.e_val(NOT_INPUT, Scope); return to_string(std::cosh(x)); } } p_cosh; DISPATCHER::INSTALL d_cosh(&function_dispatcher, "cosh", &p_cosh); /*--------------------------------------------------------------------------*/ class tan : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER x; Cmd >> x; x.e_val(NOT_INPUT, Scope); return to_string(std::tan(x)); } } p_tan; DISPATCHER::INSTALL d_tan(&function_dispatcher, "tan", &p_tan); /*--------------------------------------------------------------------------*/ class tanh : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER x; Cmd >> x; x.e_val(NOT_INPUT, Scope); return to_string(std::tanh(x)); } } p_tanh; DISPATCHER::INSTALL d_tanh(&function_dispatcher, "tanh", &p_tanh); /*--------------------------------------------------------------------------*/ class na : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER arg; Cmd >> arg; arg.e_val(NOT_INPUT, Scope); return "NA"; //return (arg.has_hard_value()) ? (to_string(double(arg))) : ("NA"); } } p_na; DISPATCHER::INSTALL d_na(&function_dispatcher, "na", &p_na); /*--------------------------------------------------------------------------*/ // random funcs: // Respectively you can give a parameter a statistical dispersion function, // either rectangular distribution // UNIF(nom_val, rel_var) // AUNIF(nom_val, abs_var) // or normal distribution: // GAUSS(nom_val, rel_var, sigma) // AGAUSS(nom_val, abs_var, sigma) // Normal distribution can be represented with variation values of 1, 2 or 3 sigmas. // In both cases rel_var=abs_var/nom_val. // for now, stubs, return nom_val /*--------------------------------------------------------------------------*/ class RANDOM_STUB : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER arg; Cmd >> arg; arg.e_val(NOT_INPUT, Scope); return to_string(double(arg)); } } p_stub; DISPATCHER::INSTALL d_stub(&function_dispatcher, "agauss|gauss|aunif|unif", &p_stub); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/globals.cc��������������������������������������������������������������������������������������0000664�0000000�0000000�00000005575�11454012162�0013607�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: globals.cc,v 26.136 2009/12/07 23:20:42 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * static objects -- construct first, destruct last */ #include "globals.h" #include "u_prblst.h" #include "e_cardlist.h" #include "u_status.h" /*--------------------------------------------------------------------------*/ // here to make sure they get constructed and destructed in proper order // first construct, last destruct // dispatchers must be constructed before any static objects they contain // and destructed after. RUN_MODE ENV::run_mode = rPRE_MAIN; DISPATCHER command_dispatcher; DISPATCHER bm_dispatcher; DISPATCHER model_dispatcher; DISPATCHER device_dispatcher; DISPATCHER language_dispatcher; DISPATCHER function_dispatcher; DISPATCHER measure_dispatcher; DISPATCHER status_dispatcher; DISPATCHER help_dispatcher; DISPATCHER probe_dispatcher; // for the rest, order should not matter, but it is convenient here CARD_LIST CARD_LIST::card_list; // root circuit PROBELIST PROBE_LISTS::alarm[sCOUNT]; /* list of alarm points */ PROBELIST PROBE_LISTS::plot[sCOUNT]; /* list of plot points */ PROBELIST PROBE_LISTS::print[sCOUNT]; /* list of print points */ PROBELIST PROBE_LISTS::store[sCOUNT]; /* list of pts to store for postproc */ // the rest of this should not be here, is residue of old stuff STATUS status; std::string head; /*--------------------------------------------------------------------------*/ /* sweep command. This will go away with a rewrite of looping */ const int swp_nest_max = 1; /* no loop, "future" expansion */ int swp_count[swp_nest_max]; /* sweep counter */ int swp_steps[swp_nest_max]; /* sweep number of steps */ int swp_type[swp_nest_max]; /* type of sweep (log or linear) */ int swp_nest; /* sweep nesting (recursion) level */ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������������������������������������������������������������������������src/globals.h���������������������������������������������������������������������������������������0000664�0000000�0000000�00000003427�11454012162�0013443�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: globals.h,v 26.136 2009/12/07 23:20:42 al Exp $ -*- C++ -*- * Copyright (C) 2007 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * declarations of globals that are exported to plugins */ #include "l_dispatcher.h" class CMD; class COMMON_COMPONENT; class MODEL_CARD; class CARD; class LANGUAGE; class FUNCTION; class CKT_BASE; class PROBELIST; extern INTERFACE DISPATCHER command_dispatcher; extern INTERFACE DISPATCHER bm_dispatcher; extern INTERFACE DISPATCHER model_dispatcher; extern INTERFACE DISPATCHER device_dispatcher; extern INTERFACE DISPATCHER language_dispatcher; extern INTERFACE DISPATCHER function_dispatcher; extern INTERFACE DISPATCHER measure_dispatcher; extern INTERFACE DISPATCHER status_dispatcher; extern INTERFACE DISPATCHER help_dispatcher; extern INTERFACE DISPATCHER probe_dispatcher; extern INTERFACE std::string head; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/io.cc�������������������������������������������������������������������������������������������0000664�0000000�0000000�00000002436�11454012162�0012564�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: io.cc,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * shared data for all io functions, initialization, default values */ //testing=trivial 2006.07.17 #include "io_.h" OMSTREAM IO::mstdout(stdout); OMSTREAM IO::error(stdout); OMSTREAM IO::plotout; bool IO::plotset(false); int IO::formaat(0); bool IO::incipher(false); FILE* IO::stream[MAXHANDLE+1] = {0, stdout, stderr}; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/io_.h�������������������������������������������������������������������������������������������0000664�0000000�0000000�00000011271�11454012162�0012562�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: io_.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * shared data for all io functions * other io related stuff, like files and formatting */ //testing=script 2006.07.17 #ifndef IO_H #define IO_H #include "l_lib.h" /*--------------------------------------------------------------------------*/ class CS; const int MAXHANDLE = CHAR_BIT*sizeof(int)-1; /*--------------------------------------------------------------------------*/ class INTERFACE OMSTREAM { private: int _mask; int _fltdig; /* max precision for float/double numbers */ int _fltwid; /* fixed(min)width for float/double numbers */ int _format; /* how to format io. Basic option. */ static unsigned _cpos[MAXHANDLE+1];/* character counter */ bool _cipher; /* flag: encrypt output file */ bool _pack; /* flag: convert whitespace to tabs on out */ OMSTREAM(int m) :_mask(m),_fltdig(7),_fltwid(0),_format(0),_cipher(false),_pack(false) {} public: explicit OMSTREAM(FILE* f = 0) :_mask(0),_fltdig(7),_fltwid(0),_format(0),_cipher(false), _pack(false) {_mask = (f) ? 1<(p));} OMSTREAM& form(const char*,...); OMSTREAM& operator<<(char c); OMSTREAM& operator<<(const char* s); OMSTREAM& operator<<(double x) {return (*this)< * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Sets up output direction and format for most commands * updates pointers into the string * outreset starts it all over */ //testing=script,sparse 2006.07.17 #include "io_.h" #include "ap.h" /*--------------------------------------------------------------------------*/ void initio(OMSTREAM&); //static void decipher(char*); void outreset(void); OMSTREAM* outset(CS&,OMSTREAM*); static FILE* file_open(CS&,const char*,const char*,FILE*); /*--------------------------------------------------------------------------*/ static FILE* fn; /* write file */ static FILE* to_pipe; /*--------------------------------------------------------------------------*/ /* initio: initialize file encryption, etc */ void initio(OMSTREAM& Where) { const char* tag = "''''"; if (Where.cipher()) { /* if writing an encrypted file, */ untested(); Where << tag << '\n'; /* mark it as encrypted */ }else{ } #if 0 if (Whence) { char buf[BUFLEN]; if (!fgets(buf, BUFLEN, Whence)) /* if the first line deciphers to */ return; /* the cipher tag, it is encrypted */ IO::incipher = true; /* otherwise, */ decipher(buf); /* rewind and read normally */ if (strcmp(buf,tag) != 0) { /* mismatch */ IO::incipher = false; fseek(Whence,0L,SEEK_SET); } } #endif } /*--------------------------------------------------------------------------*/ #if 0 /* decipher: un-encrypt a line of text in place */ void decipher(char *buf) { untested(); if (IO::incipher) { for ( ; isprint(buf[1]); buf++ ) { int fixed = static_cast(buf[1]) - static_cast(buf[0]); while (!isascii(fixed) || !isprint(fixed)) fixed += (0x7f-0x20); buf[0] = static_cast(fixed); } buf[0] = '\0'; }else{ } } #endif /*--------------------------------------------------------------------------*/ /* outreset: close files and set i/o flags to standard values */ void outreset(void) { if (to_pipe) { untested(); pclose(to_pipe); to_pipe = NULL; }else{ } xclose(&fn); IO::formaat = 0; IO::incipher = false; IO::mstdout.reset(); } /*--------------------------------------------------------------------------*/ /* outset: set up i/o for a command * return whether or not it did anything */ OMSTREAM* outset(CS& cmd, OMSTREAM* out) { bool echo = false; for (;;) { if (cmd.umatch("basic ")) { IO::formaat = ftos_EXP; (*out).setformat(ftos_EXP); }else if (cmd.umatch("cipher ")) {untested(); (*out).setcipher().setpack(); }else if (cmd.umatch("pack ")) {itested(); (*out).setpack(); }else if (cmd.umatch("quiet ")) {itested(); echo = false; (*out).detach(IO::mstdout); }else if (cmd.umatch("echo ") || cmd.umatch("list ")) {itested(); echo = true; (*out).attach(IO::mstdout); }else if (cmd.umatch("save ")) {itested(); fn = file_open(cmd,"","w",fn); (*out).attach(fn); }else if (cmd.umatch("\\|")) {untested(); // open a pipe std::string command; cmd >> command; to_pipe = popen(command.c_str(), "w"); assert(to_pipe); IO::stream[static_cast(fileno(to_pipe))] = to_pipe; (*out).attach(to_pipe); IO::formaat = ftos_EXP; (*out).setformat(ftos_EXP); if (!echo) {untested(); (*out).detach(IO::mstdout); }else{untested(); } }else if (cmd.umatch(">")) {itested(); // open a file for write or append const char *rwaflag; rwaflag = (cmd.umatch(">")) ? "a" : "w"; fn = file_open(cmd,"",rwaflag,fn); (*out).attach(fn); IO::formaat = ftos_EXP; (*out).setformat(ftos_EXP); if (!echo) {itested(); (*out).detach(IO::mstdout); }else{untested(); } }else{ break; } } return out; } /*--------------------------------------------------------------------------*/ /* file_open: a different interface for xopen */ static FILE *file_open( CS& cmd, const char *ext, const char *rwaflag, FILE *fileptr) {itested(); xclose(&fileptr); fileptr = xopen(cmd,ext,rwaflag); if (!fileptr) {itested(); throw Exception_File_Open(""); }else{itested(); } return fileptr; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/io_error.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000006037�11454012162�0013776�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: io_error.cc,v 26.83 2008/06/05 04:46:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Error handler. * Collection of functions to handle all types of errors * including user interrupts, system errors, overflow, etc. */ //testing=script,sparse 2006.07.17 #include "ap.h" #include "u_opt.h" /*--------------------------------------------------------------------------*/ void error(int,const char*,...); void error(int,const std::string&); /*--------------------------------------------------------------------------*/ #if 0 Exception_CS::Exception_CS(const std::string& Message, const CS& cmd, unsigned cursor) :Exception(Message), _cmd(cmd.fullstring()), _cursor(cursor) {untested(); } #endif /*--------------------------------------------------------------------------*/ Exception_CS::Exception_CS(const std::string& Message, const CS& cmd) :Exception(Message), _cmd(cmd.fullstring()), _cursor(cmd.cursor()) {itested(); } /*--------------------------------------------------------------------------*/ const std::string Exception_CS::message()const {itested(); std::string s; if (_cursor < 40) {itested(); s = _cmd.substr(0,60) + '\n' + std::string(_cursor, ' ') + "^ ? " + Exception::message(); }else{untested(); s = "... " + _cmd.substr(_cursor-36, 56) + "\n ^ ? " + Exception::message(); } return s; } /*--------------------------------------------------------------------------*/ /* error: error message printer * print it, if severe enough * terminate command, if really bad */ void error(int badness, const char* fmt, ...) { if (badness >= OPT::picky) { char buffer[BIGBUFLEN] = ""; va_list arg_ptr; va_start(arg_ptr,fmt); vsprintf(buffer,fmt,arg_ptr); va_end(arg_ptr); IO::error << buffer; }else{ } } /*--------------------------------------------------------------------------*/ void error(int badness, const std::string& message) { if (badness >= OPT::picky) { IO::error << message; }else{ } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/io_error.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000007670�11454012162�0013644�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: io_error.h,v 26.130 2009/11/15 21:51:59 al Exp $ -*- C++ -*- * data for error and exception handling * * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=trivial 2006.07.17 #ifndef bDANGER //#include "md.h" included by //#include "io_trace.h" /*--------------------------------------------------------------------------*/ /* arg to error() (badness) to decide severity of exception */ #define bNOERROR 0 #define bTRACE 1 #define bLOG 2 #define bDEBUG 3 #define bPICKY 4 #define bWARNING 5 #define bDANGER 6 INTERFACE void error(int,const char*,...); INTERFACE void error(int,const std::string&); INTERFACE std::string to_string(int); /*--------------------------------------------------------------------------*/ struct Exception { std::string _message; virtual const std::string message()const {return _message;} Exception(const std::string& Message) :_message(Message) { } virtual ~Exception() {} }; class CS; struct Exception_CS :public Exception { std::string _cmd; unsigned _cursor; const std::string message()const; //Exception_CS(const std::string& Message, const CS& cmd, unsigned cursor); Exception_CS(const std::string& Message, const CS& cmd); }; struct Exception_No_Match :public Exception{ std::string _key; Exception_No_Match(const std::string& key) :Exception("no match: " + key), _key(key) { } }; struct Exception_Cant_Find :public Exception{ std::string _device, _key, _scope; Exception_Cant_Find(const std::string& dev, const std::string& key, const std::string& scope) :Exception(dev + ": can't find: " + key + " in " + scope), _device(dev), _key(key), _scope(scope) { } Exception_Cant_Find(const std::string& dev, const std::string& key) :Exception(dev + ": can't find: " + key), _device(dev), _key(key), _scope("") { } }; struct Exception_Too_Many :public Exception{ int _requested, _max, _offset; Exception_Too_Many(int requested, int max, int offset) :Exception("too many: requested=" + to_string(requested+offset) + " max=" + to_string(max+offset)), _requested(requested), _max(max), _offset(offset) {untested(); } }; struct Exception_Type_Mismatch :public Exception{ std::string _device, _name, _need_type; Exception_Type_Mismatch(const std::string& dev, const std::string& name, const std::string& type) :Exception(dev + ": " + name + " is not a " + type), _device(dev), _name(name), _need_type(type) { } }; struct Exception_Model_Type_Mismatch :public Exception{ std::string _device, _modelname, _need_type; Exception_Model_Type_Mismatch(const std::string& d, const std::string& m, const std::string& n) :Exception(d + ": model " + m + " is not a " + n), _device(d), _modelname(m), _need_type(n) { } }; struct Exception_End_Of_Input :public Exception{ Exception_End_Of_Input(const std::string& Message) :Exception(Message) { } }; struct Exception_File_Open :public Exception{ Exception_File_Open(const std::string& Message) :Exception(Message) { } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ������������������������������������������������������������������������src/io_findf.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000005271�11454012162�0013732�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: io_findf.cc,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Modified by AD. Sent to me by C-WARE * This file contains the routine to locate a file, * using a path string for the directories to search. * Interface: * findfile(filename, paths, mode) * filename is the name of the file to be searched for, * paths is the path to follow to find it. * mode is how you want to open the file * returns full path name, if successful, else "". * * PATHSEP, ENDDIR are system dependent, defined in md.h */ //testing=script,sparse 2006.07.17 #include "l_lib.h" /*--------------------------------------------------------------------------*/ std::string findfile(const std::string& filename, const std::string& path, int mode) { #ifdef CHECK_LOCAL_FIRST if (OS::access_ok(filename, mode)) { untested(); return filename; }else{ untested(); } #endif // for each item in the path for (std::string::const_iterator p_ptr=path.begin(); p_ptr!=path.end(); ++p_ptr) { // p_ptr changed internally ^^^^^ skip sep std::string target = ""; while (*p_ptr != PATHSEP && p_ptr != path.end()) { // copy 1 path item target += *p_ptr++; } if (!target.empty() && !strchr(ENDDIR,p_ptr[-1])) { target += *ENDDIR; // append '/' if needed }else{untested(); } target += filename; if (OS::access_ok(target, mode)) {untested(); // found it return target; }else if (p_ptr==path.end()) { // ran out of path, didn't find it return ""; }else{ // else try again } } return ""; // path doesn't exist - didn't go thru loop at all } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/io_out.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000014625�11454012162�0013456�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: io_out.cc,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * output text to files, devices, or whatever * m???? = multiple output to a bunch of io devices. * with character count (so tab will work) * Will start a new line first if the entire output will not fit. * so wrap will not break a word or number. * Where is a bit mask of places to send the output. * A possible portability problem exists with the handle numbers. * It assumes they start at 0, and count up, and that there are no more than * the number of bits in an integer (MAXHANDLE). * but I have yet to find a system that did not meet this form. */ //testing=script,sparse 2006.07.17 #include "u_opt.h" /*--------------------------------------------------------------------------*/ const char* octal(int x); // OMSTREAM & OMSTREAM::tab(int count) // OMSTREAM & OMSTREAM::form(const char*,...); // OMSTREAM & OMSTREAM::operator<<(const char *str) // OMSTREAM & OMSTREAM::operator<<(char chr) /*--------------------------------------------------------------------------*/ unsigned OMSTREAM::_cpos[MAXHANDLE+1]; /* character counter */ /*--------------------------------------------------------------------------*/ /* octal: make octal string for an int */ const char* octal(int x) { static char s[sizeof(int)*3+1]; sprintf(s, "%o", x); return s; } /*--------------------------------------------------------------------------*/ /* mtab: tab to column "count" on output devices "where" * by outputting spaces. * If already beyond, start new line, then tab to column. */ OMSTREAM & OMSTREAM::tab(unsigned count) { for (int ii=0, mm=1; ii<=MAXHANDLE; ++ii, mm<<=1) { if (_mask & mm) { OMSTREAM this_file(_mask & mm); if (_cpos[ii] > count) { this_file << '\n'; }else{ } while (_cpos[ii]= OPT::outwidth && _cpos[ii] != 0) { OMSTREAM this_file(_mask & mm); this_file << '\n' << '+'; }else{ } /* see if it fits .... */ if (_cpos[ii]==0) { /* if not, next line */ newline = true; }else{ } } if (cipher() && newline) {untested(); *this << '\t'; }else{ } while (*str && (str[1] || *str != '@')) { *this << *str++; } return *this; } /*--------------------------------------------------------------------------*/ /* mputc: multiple putc * multiple putc * also.... * crunch spaces, if selected * encripts, if selected * keeps track of character count */ OMSTREAM & OMSTREAM::operator<<(char chr) { if (_mask & 1) { unreachable(); _mask &= ~1; error(bDANGER, "internal error: out to stdin\n"); }else{ } static int old = '\0'; static int cchr = 'w'; /* starting encryption seed */ /* arbitrary printable character */ bool count; if (chr=='\t') {itested(); chr = ' '; count = false; }else{ count = true; } bool suppress = (pack() && old==' ' && chr==' '); old = chr; if (cipher() && !suppress && isprint(chr)) {untested(); cchr += static_cast(chr); while (!isascii(cchr) || !isprint(cchr)) {untested(); cchr -= (0x7f-0x20); } chr = static_cast(cchr); }else{ } for (int ii=0, mm=1; ii<=MAXHANDLE; ++ii, mm<<=1) { if (_mask & mm) { assert(IO::stream[ii]); if (chr=='\b') {untested(); --_cpos[ii]; fflush(IO::stream[ii]); }else if (count) { ++_cpos[ii]; }else{itested(); } if (chr=='\n') { _cpos[ii] = 0; fflush(IO::stream[ii]); }else if (chr=='\r') {itested(); if (_cpos[ii] == 0) {untested(); suppress = true; }else{itested(); _cpos[ii] = 0; fflush(IO::stream[ii]); } }else{ } if (!suppress) { fputc(chr,IO::stream[ii]); }else{itested(); } }else{ } } return *this; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������������������������������������������������src/io_trace.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000005556�11454012162�0013612�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: io_trace.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * trace macros for model debugging */ //testing=trivial 2006.07.17 /* allow multiple inclusions with different DO_TRACE */ #undef trace_line #undef trace0 #undef trace1 #undef trace2 #undef trace3 #undef trace4 #undef trace5 #undef untested #undef unreachable #undef incomplete /*--------------------------------------------------------------------------*/ #ifdef DO_TRACE #define trace_line() (printf("@@#\n@#@:%s:%u:%s\n", \ __FILE__, __LINE__, __func__)) #define trace0(s) (printf("@#@%s\n", s)) #define trace1(s,x) (printf("@#@%s %s=%g\n", s, #x, (double)(x))) #define trace2(s,x,y) (printf("@#@%s %s=%g %s=%g\n",\ s, #x, (double)(x), #y, (double)(y))) #define trace3(s,x,y,z) (printf("@#@%s %s=%g %s=%g %s=%g\n",\ s, #x, (double)(x), #y, (double)(y), #z, (double)(z))) #define trace4(s,w,x,y,z)(printf("@#@%s %s=%g %s=%g %s=%g %s=%g\n",\ s, #w, (double)(w), #x, (double)(x), #y, (double)(y), #z, (double)(z))) #define trace5(s,v,w,x,y,z)\ (printf("@#@%s %s=%g %s=%g %s=%g %s=%g %s=%g\n",\ s, #v, (double)(v), #w, (double)(w), #x, (double)(x),\ #y, (double)(y), #z, (double)(z))) #else #define trace_line() #define trace0(s) #define trace1(s,x) #define trace2(s,x,y) #define trace3(s,x,y,z) #define trace4(s,w,x,y,z) #define trace5(s,v,w,x,y,z) #endif #define unreachable() (printf("@@#\n@@@unreachable:%s:%u:%s\n", \ __FILE__, __LINE__, __func__)) #define incomplete() (printf("@@#\n@@@incomplete:%s:%u:%s\n", \ __FILE__, __LINE__, __func__)) #ifdef TRACE_UNTESTED #define untested() (printf("@@#\n@@@:%s:%u:%s\n", \ __FILE__, __LINE__, __func__)) #else #define untested() #endif #ifdef TRACE_ITESTED #define itested() (printf("@@#\n@@@:%s:%u:%s\n", \ __FILE__, __LINE__, __func__)) #else #define itested() #endif /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������������������������������������������������������������������src/io_xopen.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000010071�11454012162�0013767�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: io_xopen.cc,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * scan a string for a file name * fill in extension, if necessary * open file */ //testing=script,sparse 2006.07.17 #include "u_opt.h" #include "constant.h" #include "ap.h" /*--------------------------------------------------------------------------*/ void xclose(FILE**); FILE* xopen(CS&,const char*,const char*); /*--------------------------------------------------------------------------*/ void xclose(FILE **fn) { if (*fn) { fclose(*fn); *fn = NULL; } } /*--------------------------------------------------------------------------*/ /* xopen: open a file from a command string * scan and eat up the name from the command * add default extension if appropriate * if there is no name, prompt for one * trap errors of not found and clobber */ FILE *xopen(CS& cmd, const char *ext, const char *how) { char fname[BIGBUFLEN]; cmd.skipbl(); if (cmd.is_end()) {untested(); cmd = getcmd("file name? ",fname, BIGBUFLEN); } /* copy the name */ cmd.skipbl(); /* and while we're at it ... */ { /* find out if we want to add the */ bool defalt = true; /* default extension */ size_t i; for (i = 0; i < BIGBUFLEN; ) { char c = cmd.ctoc(); if (!c || isspace(c)) { break; } if (c == '$') {untested(); sprintf(&(fname[i]), "%ld", static_cast(time(0))); i = strlen(fname); }else{ /* we want to add the extension */ fname[i++] = c; /* if it doesn't already have one, */ if (c == '.') { /* as determined by a '.' */ defalt = false; /* not before the directory */ }else if (strchr(ENDDIR,c)) { /* separator-terminator character */ itested(); defalt = true; /* '\' or '/' for msdos, */ } } /* ']' or '/' for vms, */ } /* '/' for unix (in ENDDIR) */ cmd.skip(-1); if (defalt && ext && *ext && i+strlen(ext)+2 < BIGBUFLEN) {untested(); fname[i++] = '.'; /* add the extension (maybe) */ strcpy(&fname[i],ext); }else{ fname[i] = '\0'; } } trim(fname); if (strlen(fname)==0) { return NULL; } cmd.skipcom(); FILE *code = NULL; /* a file pointer for the file we found */ if (!OPT::clobber && (*how == 'w') && (access(fname,F_OK) == FILE_OK)) {untested(); char buffer[BUFLEN]; std::string msg = std::string(fname) + " exists. replace? "; getcmd(msg.c_str(), buffer, BUFLEN); if (Umatch(buffer,"y{es} ")) {untested(); /* should be new file, but */ code = fopen(fname,how); /* file already exists, ask */ }else{untested(); return NULL; } }else{ code = fopen(fname,how); } if (code && fileno(code)>MAXHANDLE) {untested(); error(bWARNING, "internal error: files: %d\n", fileno(code)); fclose(code); code = NULL; } if (code) { IO::stream[static_cast(fileno(code))] = code; }else{itested(); error(bWARNING, "can't open %s, %s\n", fname, strerror(errno)); } return code; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/l_compar.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000003257�11454012162�0013615�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: l_compar.h,v 26.98 2008/10/24 06:10:07 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script,complete 2006.07.13 #ifndef L_COMPAR_H #define L_COMPAR_H #include "md.h" /*--------------------------------------------------------------------------*/ /* uporder: returns true if a,b,c are in non-decreasing order */ template inline bool up_order(T a, T b, T c) { return (a<=b) && (b<=c); } /* inorder: returns true if b is between a and c */ template inline bool in_order(T a, T b, T c) { return up_order(a,b,c) || up_order(c,b,a); } /* torange: returns b, clipped to range a..c */ template inline T to_range(T a, T b, T c) { return std::min(std::max(a,b),c); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/l_denoise.h�������������������������������������������������������������������������������������0000664�0000000�0000000�00000004550�11454012162�0013757�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: l_denoise.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * functions to "de-noise" arithmetic * attempt to get rid of noise due to roundoff */ //testing=script,complete 2006.07.13 #ifndef L_DENOISE_H #define L_DENOISE_H #include "u_opt.h" /*--------------------------------------------------------------------------*/ /* fixzero: force numbers near zero to zero - changes thru pointer */ inline void fixzero(double *z, double r) { assert(z); assert(*z == *z); assert(r == r); if (std::abs(*z) < std::abs(r*OPT::roundofftol)) { *z=0.; } } /*--------------------------------------------------------------------------*/ /* fixzero: force numbers near zero to zero - returns value */ inline double fixzero(double z, double r) { assert(z == z); assert(r == r); return (std::abs(z) < std::abs(r*OPT::roundofftol)) ? 0. : z; } /*--------------------------------------------------------------------------*/ /* dn_diff: de-noised difference */ inline double dn_diff(double a, double b) { assert(a == a); assert(b == b); return fixzero(a-b, a); } /*--------------------------------------------------------------------------*/ #if 0 /* dn_sum: de-noised sum */ inline double dn_sum(double a, double b) { untested(); assert(a == a); assert(b == b); return fixzero(a+b, a); } #endif /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������src/l_dispatcher.h����������������������������������������������������������������������������������0000664�0000000�0000000�00000012535�11454012162�0014461�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: l_dispatcher.h,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2006 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * dispatcher -- for dynamically loaded modules */ //testing=informal #ifndef L_DISPATCHER_H #define L_DISPATCHER_H #include "l_stlextra.h" #include "u_opt.h" #include "ap.h" /*--------------------------------------------------------------------------*/ template class INTERFACE DISPATCHER { private: std::map * _map; public: DISPATCHER() { if (!_map) { _map = new std::map; }else{ } } typedef typename std::map::const_iterator const_iterator; //class const_iterator : public std::map::const_iterator {}; const_iterator begin()const {assert(_map); return _map->begin();} const_iterator end()const {assert(_map); return _map->end();} void install(const std::string& s, T* p) { assert(s.find(',', 0) == std::string::npos); if (!_map) { _map = new std::map; }else{ } trace0(s.c_str()); // loop over all keys, separated by '|' for (std::string::size_type // bss: begin sub-string bss = 0, ess = s.find('|', bss); // ess: end sub-string bss != std::string::npos; bss = (ess != std::string::npos) ? ess+1 : std::string::npos, ess = s.find('|', bss)) { std::string name = s.substr(bss, (ess != std::string::npos) ? ess-bss : std::string::npos); trace2(name.c_str(), bss, ess); if (name == "") { // quietly ignore empty string }else if ((*_map)[name]) { // duplicate .. stash the old one so we can get it back error(bWARNING, name + ": already installed, replacing\n"); std::string save_name = name + ":0"; for (int ii = 0; (*_map)[save_name]; ++ii) { save_name = name + ":" + to_string(ii); } (*_map)[save_name] = (*_map)[name]; error(bWARNING, "stashing as " + save_name + "\n"); }else{ // it's new, just put it in } (*_map)[name] = p; } } void uninstall(T* p) { assert(_map); for (typename std::map::iterator ii = _map->begin(); ii != _map->end(); ++ii) { if (ii->second == p) { ii->second = NULL; }else{ } } #if !defined(NDEBUG) for (typename std::map::iterator ii = _map->begin(); ii != _map->end(); ++ii) { assert(ii->second != p); } #endif } void uninstall(const std::string& s) { assert(_map); // loop over all keys, separated by '|' for (std::string::size_type // bss: begin sub-string bss = 0, ess = s.find('|', bss); // ess: end sub-string bss != std::string::npos; bss = (ess != std::string::npos) ? ess+1 : std::string::npos, ess = s.find('|', bss)) { std::string name = s.substr(bss, (ess != std::string::npos) ? ess-bss : std::string::npos); if (name == "") { // quietly ignore empty string }else if ((*_map)[name]) { // delete, try to get back the old one int ii = 0; std::string save_name = name + ":0"; for (ii = 0; (*_map)[save_name]; ++ii) { save_name = name + ":" + to_string(ii); } if (ii > 1) { save_name = name + ":" + to_string(ii-2); (*_map)[name] = (*_map)[save_name]; (*_map)[save_name] = NULL; error(bWARNING, "restoring " + save_name + " as " + name + "\n"); }else{ (*_map)[name] = NULL; } }else{ error(bWARNING, name + ": not installed, doing nothing\n"); } } } T* operator[](std::string s) { assert(_map); T* rv = (*_map)[s]; if (!rv && OPT::case_insensitive) { notstd::to_lower(&s); rv = (*_map)[s]; }else{ } return rv; } T* operator[](CS& cmd) { unsigned here = cmd.cursor(); std::string s; cmd >> s; //------------------------ T* p = (*this)[s]; //------------------------ if (!p) { cmd.reset(here); }else{ } return p; } T* clone(std::string s) { T* proto = (*this)[s]; if (proto) { return proto->clone(); }else{itested(); return NULL; } } class INSTALL { private: const std::string _name; DISPATCHER* _d; T* _p; public: INSTALL(DISPATCHER* d, const std::string& name, T* p) : _name(name), _d(d), _p(p) { assert(_d); assert(p); _d->install(_name, p); } ~INSTALL() { //_d->uninstall(_name); _d->uninstall(_p); } }; }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������src/l_ftos.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000017716�11454012162�0013452�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: l_ftos.cc,v 26.96 2008/10/09 05:36:27 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * float to string * builds string representing floating number * num = number to convert. * str = string to put it in. Must be big enough, or else!! * Must have length at least len+6. * sig digits + dec.pt.(1) + sign(1) + exp(4) * len = max number of displayed digits. (left + right of dp) * (includes d.p. if 'e' notation and 2 digit exp) * fmt = format : 0 = alpha for exp notation * FMTEXP = exponential notation * FMTSIGN = always inlcude sign * FMTFILL = fill in zeros * //BUG// * returns a pointer to static space where the string is. * there is a finite pool, so repeated calls work, to a point. * after that, the space is overwritten, every POOLSIZE calls */ //testing=script 2005.10.11 #include "l_lib.h" #include "constant.h" /*--------------------------------------------------------------------------*/ char* ftos(double,int,int,int); /*--------------------------------------------------------------------------*/ const int POOLSIZE = 100; const int MAXLENGTH = 40; static double ftos_floor = 1e-99; /*--------------------------------------------------------------------------*/ std::string to_string(unsigned n) { char s[100]; sprintf(s, "%u", n); return s; } /*--------------------------------------------------------------------------*/ std::string to_string(int n) { char s[100]; sprintf(s, "%d", n); return s; } /*--------------------------------------------------------------------------*/ std::string to_string(double n) { return ftos(n, 0, 7, 0); } /*--------------------------------------------------------------------------*/ char* ftos(double num, int fieldwidth, int len, int fmt) // num = number to convert // fieldwidth = size for fixed width, 0 for variable width // len = max length of new string // fmt = how to format it { if (len < 3) { untested(); len = 3; } if (len > MAXLENGTH-6) { untested(); len = MAXLENGTH-6; } if (fieldwidth > MAXLENGTH-1) { untested(); fieldwidth = MAXLENGTH-1; } char *str; { /* get a buffer from the pool */ //BUG// It is possible to have too many buffers active // then the extras are overwritten, giving bad output // There are no known cases, but it is not checked. static char strpool[POOLSIZE][MAXLENGTH]; static int poolindex = 0; ++poolindex; if (poolindex >= POOLSIZE) { poolindex = 0; } str = strpool[poolindex]; } { /* build a clean blank string */ int string_size = std::max(fieldwidth, len+6); for (int iii=0; iii::infinity()) { untested(); strncpy(str," Over", 5); }else if (num == -std::numeric_limits::infinity()) { untested(); strncpy(str,"-Over", 5); }else if (num == std::numeric_limits::quiet_NaN()) { untested(); strncpy(str," NaN", 4); }else if (num == std::numeric_limits::signaling_NaN()) { untested(); strncpy(str," NaN", 4); }else #endif if (num == NOT_VALID) { strncpy(str," ??", 3); }else if (num == NOT_INPUT) { strncpy(str," NA", 3); }else if (num >= BIGBIG) { strncpy(str," Inf", 4); }else if (num <= -BIGBIG) { strncpy(str,"-Inf", 4); }else if (num != num) { strncpy(str," NaN", 4); }else{ if (std::abs(num) < ftos_floor) { /* hide noise */ num = 0.; } int expo = 0; /* exponent */ int nnn = 0; /* char counter -- pos in string */ if (num == 0.) { strcpy(str, " 0."); nnn = static_cast(strlen(str)); /* num==0 .. build string 0.000... */ while (--len) { str[nnn++] = '0'; } assert(expo == 0); }else{ /* num != 0 */ { // insert sign if (num < 0.) { str[0] = '-'; num = -num; }else if (fmt & ftos_SIGN) { untested(); str[0] = '+'; }else{ assert(str[0] == ' '); } } { // scale to .001 - 1.0. adjust expo. expo = -3; while (num < .001) { num *= 1000.; expo -= 3; } while (num >= 1.) { num *= .001; expo += 3; } } { // adjust len to compensate for length of printed exponent if ((fmt&ftos_EXP && expo<-9) || expo>10 || expo<-16) { --len; /* one less digit if 'e' notation */ } /* and exp is 2 digits */ if (len < 3) { untested(); ++len; } } { // round to correct number of digits double rnd = .5 / pow(10., len); /* find amt to add to round */ if (num < .01) { rnd /= 100.; }else if (num < .1) { rnd /= 10.; } num += rnd; /* add it */ if (num >= 1.) { num *= .001; /* created an extra digit: rescale */ expo += 3; } } { // build mantissa nnn = 1; if (expo == -3) { /* .001 is preferable to 1e-3 */ int flg = 0; /* print in fixed point, no exponent*/ expo = 0; str[nnn++] = '0'; str[nnn++] = '.'; while (len > 0) { num *= 10.; int digit = static_cast(floor(num)); num -= static_cast(digit); str[nnn++] = static_cast(digit + '0'); if ((flg += digit)) { --len; } } }else{ int flg = 0; for (int iii=2; len>0; --iii) {/* mantissa */ num *= 10.; /* get next digit */ int digit = static_cast(floor(num)); num -= static_cast(digit);/* subtract off last digit */ if ((flg += digit)) { /* if int part !=0 */ str[nnn++]=static_cast(digit+'0');/*(not all zeros so far)*/ --len; /* stuff the digit into the string */ } if (iii==0) { /* if we found the dec.pt. and */ str[nnn++] = '.'; /* haven't used up all the space */ } /* put a dec.pt. in the string */ } } } } assert(nnn > 0); assert(str[nnn] == ' ' || str[nnn] == '\0'); { // suppress trailing zeros if (!(fmt&ftos_FILL)) { while (str[--nnn]=='0') { str[nnn] = static_cast((nnn < fieldwidth) ? ' ' : '\0'); } ++nnn; }else{ untested(); } } { // append exponent if (expo == 0) { // nothing; }else if (fmt&ftos_EXP || expo>10 || expo<-16) {/* exponential format */ char c = str[nnn+4]; sprintf(&str[nnn], ((expo < 100) ? "E%+-3d" : "E%3u"), expo); nnn+=4; str[nnn++] = c; }else{ /* if letter-scale format */ str[nnn++] = "fpnum KMGT"[(expo+15)/3];/* put the appropriate letter*/ } /* note that letter-scale is not valid */ /* for exp==-3 or exp not in -15..+12 */ /* this is trapped but letter-scale is also */ /* not valid if exp not divisible by 3. */ /* This is not trapped, since it supposedly */ /* cant happen. */ if (str[nnn-1] == 'M') { str[nnn++] = 'e'; /* Spice kluge "MEG" */ str[nnn++] = 'g'; } } } { // clean up trailing blanks if (fieldwidth==0) { trim(str); } } return str; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������src/l_lib.h�����������������������������������������������������������������������������������������0000664�0000000�0000000�00000005337�11454012162�0013103�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: l_lib.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script 2006.07.13 #ifndef L_LIB_H #define L_LIB_H #include "md.h" /*--------------------------------------------------------------------------*/ char* trim(char*); INTERFACE bool Umatch(const std::string&, const std::string&); INTERFACE bool wmatch(const std::string& s1,const std::string& s2); INTERFACE std::string to_string(unsigned); INTERFACE std::string to_string(int); INTERFACE std::string to_string(double); INTERFACE char* ftos(double,int,int,int); /*--------------------------------------------------------------------------*/ //ftos stuff enum { /* formatting bit-fields */ ftos_DEFAULT = 0, /* default formatting, with letters */ ftos_EXP = 1, /* use 'e' notation, almost like printf */ ftos_SIGN = 2, /* always include sign */ ftos_FILL = 4 /* fill in trailing zeros */ }; /*--------------------------------------------------------------------------*/ // wrappers for old standard C lpbrary namespace OS { inline void system(const std::string& s) {itested(); ::system(s.c_str()); } inline void chdir(const std::string& s) {itested(); ::chdir(s.c_str()); } inline void remove(const std::string& s) {itested(); ::remove(s.c_str()); } inline bool access_ok(const std::string& file, int mode) { return (::access(file.c_str(), mode) == 0/*file_ok*/); } inline std::string getcwd() {itested(); char buf[BUFLEN+1]; char* cwd = ::getcwd(buf,BUFLEN); if (cwd) {itested(); return cwd; }else{untested(); return ""; } } inline std::string getenv(const std::string& s) { char* ev = ::getenv(s.c_str()); if (ev) { return ev; }else{itested(); return ""; } } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/l_pmatch.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000003542�11454012162�0013743�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: l_pmatch.cc,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * string compare * compares characters until end of first string * any non-alpha character is a terminator * returns offset into string to legal start of next token * (skips trailing spaces and comma, if any) * if they match so far, and enough matched, else NO (0) * Characters in reference string in UPPER case must match. * Always requires at least one character to match. */ //testing=script,complete 2006.07.13 #include "ap.h" #include "l_lib.h" /*--------------------------------------------------------------------------*/ bool Umatch(const std::string& str1, const std::string& str2) { CS cmd(CS::_STRING, str1); //call to CS member on string if (cmd.umatch(str2)) { return true; }else{ return 0; } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������src/l_stlextra.h������������������������������������������������������������������������������������0000664�0000000�0000000�00000005166�11454012162�0014203�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: l_stlextra.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * extra functions in the STL style * Things that ought to be there, but are not */ //testing=script,complete 2006.07.13 #ifndef L_STLEXTRA_H #define L_STLEXTRA_H #include "md.h" /*--------------------------------------------------------------------------*/ namespace notstd { /*--------------------------------------------------------------------------*/ template void copy_n(InputIter first, Size count, OutputIter result) { for ( ; count > 0; --count) { *result++ = *first++; } } /*--------------------------------------------------------------------------*/ /* find_ptr: like the stl find, except that the list contains pointers Dereference the pointer in the list, then compare */ template InputIterator find_ptr(InputIterator first,InputIterator last,const T& value) { while (first != last && **first != value) { ++first; } return first; } /*--------------------------------------------------------------------------*/ inline void to_lower(std::string* s) { assert(s); for (std::string::iterator i = s->begin(); i != s->end(); ++i) { *i = static_cast(tolower(*i)); } } /*--------------------------------------------------------------------------*/ inline void to_upper(std::string* s) { assert(s); for (std::string::iterator i = s->begin(); i != s->end(); ++i) { *i = static_cast(toupper(*i)); } } /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/l_timer.cc��������������������������������������������������������������������������������������0000664�0000000�0000000�00000007460�11454012162�0013612�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: l_timer.cc,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Time a command, or whatever */ //testing=script,sparse 2006.07.13 #include "l_timer.h" /*--------------------------------------------------------------------------*/ // TIMER::TIMER(); // TIMER::TIMER(const char*); // TIMER& TIMER::fullreset(); // TIMER& TIMER::reset(); // TIMER& TIMER::start(); // TIMER& TIMER::stop(); // TIMER& TIMER::check(); // TIMER& TIMER::print(); // TIMER& TIMER::operator=(const TIMER&); TIMER operator-(const TIMER&,const TIMER&); /*--------------------------------------------------------------------------*/ inline double run_time() { return static_cast(clock()) / static_cast(CLOCKS_PER_SEC); } /*--------------------------------------------------------------------------*/ TIMER::TIMER() { fullreset(); } /*--------------------------------------------------------------------------*/ TIMER::TIMER(const std::string& label) :_name(label) { fullreset(); } /*--------------------------------------------------------------------------*/ TIMER& TIMER::fullreset() { _total = 0.; return reset(); } /*--------------------------------------------------------------------------*/ TIMER& TIMER::reset() { _last = 0.; _ref = 0.; _running = false; return *this; } /*--------------------------------------------------------------------------*/ TIMER& TIMER::start() { assert(!_running); if (_running) { untested(); stop(); } _ref = run_time(); _running = true; return *this; } /*--------------------------------------------------------------------------*/ TIMER& TIMER::stop() { if (_running) { double runtime = run_time() - _ref; _ref = 0.; _last += runtime; _total += runtime; _running = false; } return *this; } /*--------------------------------------------------------------------------*/ TIMER& TIMER::check() { itested(); if (_running) { itested(); stop(); start(); }else{ untested(); } return *this; } /*--------------------------------------------------------------------------*/ TIMER& TIMER::print(OMSTREAM& s) { s.form("%10s %8.2f %8.2f\n", _name.c_str(), _last, _total); return *this; } /*--------------------------------------------------------------------------*/ TIMER& TIMER::operator=(const TIMER& x) { _last = x._last; _ref = x._ref; _total = x._total; _running = x._running; // but don't copy the name return *this; } /*--------------------------------------------------------------------------*/ TIMER operator-(const TIMER& x, const TIMER& y) { TIMER z("temp"); z._last = x._last - y._last; z._ref = 0.; // when did the difference start running? z._total = x._total - y._total; z._running = false; // but don't copy the name return z; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/l_timer.h���������������������������������������������������������������������������������������0000664�0000000�0000000�00000004126�11454012162�0013450�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: l_timer.h,v 26.83 2008/06/05 04:46:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * CPU time accounting */ //testing=script 2006.07.13 #ifndef L_TIMER_H #define L_TIMER_H #include "io_.h" /*--------------------------------------------------------------------------*/ class OMSTREAM; /*--------------------------------------------------------------------------*/ class INTERFACE TIMER { private: double _ref; // time the clock was started double _last; // time of timed operation double _total; // time since program start bool _running; std::string _name; public: explicit TIMER(); explicit TIMER(const std::string&); ~TIMER() {} TIMER& fullreset(); TIMER& reset(); TIMER& start(); TIMER& stop(); TIMER& check(); double elapsed()const {itested();return _last;} bool is_running()const {return _running;} TIMER& print(OMSTREAM& s = IO::mstdout); TIMER& operator=(const TIMER&); friend INTERFACE TIMER operator-(const TIMER&,const TIMER&); }; template T& operator<<(T & s, TIMER & t) {t.print(s); return s;} /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/l_trim.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000003105�11454012162�0013435�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: l_trim.cc,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * remove whitespace from the end of strings */ //testing=script,complete 2006.07.13 #include #include /*--------------------------------------------------------------------------*/ char* trim(char*); /*--------------------------------------------------------------------------*/ char* trim(char *string) { size_t idx = strlen(string); while (idx > 0 && !isgraph(string[--idx])) { string[idx] = '\0' ; } return string; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/l_wmatch.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000005176�11454012162�0013757�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: l_wmatch.cc,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * wmatch: string match with wild cards * s1 may have wild cards: ? any character matches; * any repeated 0 or more * returns true or false * normally not case sensitive, * but \ before any letter in s1 forces exact match * recursive */ //testing=script 2006.07.13 #include #include "u_opt.h" #include "l_lib.h" /*--------------------------------------------------------------------------*/ static char fix_case(char c) { return ((OPT::case_insensitive) ? (static_cast(tolower(c))) : (c)); } /*--------------------------------------------------------------------------*/ bool wmatch_by_ptr(const char *s2, const char *s1) { if (!*s2 && !*s1) { // both end together -- match return true; }else if (!*s2 || !*s1) { // ends don't match return false; }else if (fix_case(*s2) == fix_case(*s1)) { // one char matches - move on return wmatch_by_ptr(s2+1, s1+1); }else if (*s1 == '?') { // ? wild card match - move on return wmatch_by_ptr(s2+1, s1+1); }else if (*s1 == '*') { // * (repeat) wild card match if (wmatch_by_ptr(s2+1, s1)) { // match 1, try for 2 return true; }else if (wmatch_by_ptr(s2, s1+1)) {itested(); // match 0 - continue return true; }else{ // match 1, only 1 return wmatch_by_ptr(s2+1, s1+1); } }else{ // mismatch return false; } } /*--------------------------------------------------------------------------*/ bool wmatch(const std::string& s1,const std::string& s2) { return wmatch_by_ptr(s1.c_str(), s2.c_str()); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/lang_spectre.cc���������������������������������������������������������������������������������0000664�0000000�0000000�00000031306�11454012162�0014621�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: lang_spectre.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2007 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include "c_comand.h" #include "d_dot.h" #include "d_coment.h" #include "d_subckt.h" #include "e_model.h" #include "u_lang.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class LANG_SPECTRE : public LANGUAGE { public: std::string name()const {return "spectre";} bool case_insensitive()const {return false;} UNITS units()const {return uSI;} public: // override virtual, used by callback std::string arg_front()const {return " ";} std::string arg_mid()const {return "=";} std::string arg_back()const {return "";} public: // override virtual, called by commands void parse_top_item(CS&, CARD_LIST*); DEV_COMMENT* parse_comment(CS&, DEV_COMMENT*); DEV_DOT* parse_command(CS&, DEV_DOT*); MODEL_CARD* parse_paramset(CS&, MODEL_CARD*); MODEL_SUBCKT* parse_module(CS&, MODEL_SUBCKT*); COMPONENT* parse_instance(CS&, COMPONENT*); std::string find_type_in_string(CS&); private: // override virtual, called by print_item void print_paramset(OMSTREAM&, const MODEL_CARD*); void print_module(OMSTREAM&, const MODEL_SUBCKT*); void print_instance(OMSTREAM&, const COMPONENT*); void print_comment(OMSTREAM&, const DEV_COMMENT*); void print_command(OMSTREAM& o, const DEV_DOT* c); private: // local void print_args(OMSTREAM&, const CARD*); } lang_spectre; DISPATCHER::INSTALL d(&language_dispatcher, lang_spectre.name(), &lang_spectre); /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ static void parse_type(CS& cmd, CARD* x) { assert(x); std::string new_type; cmd >> new_type; x->set_dev_type(new_type); } /*--------------------------------------------------------------------------*/ static void parse_args(CS& cmd, CARD* x) { assert(x); unsigned here = 0; while (cmd.more() && !cmd.stuck(&here)) { std::string name = cmd.ctos("=", "", ""); cmd >> '='; std::string value = cmd.ctos("", "(", ")"); try{ x->set_param_by_name(name, value); }catch (Exception_No_Match&) {untested(); cmd.warn(bDANGER, here, x->long_label() + ": bad parameter " + name + " ignored"); } } } /*--------------------------------------------------------------------------*/ static void parse_label(CS& cmd, CARD* x) { assert(x); std::string my_name; cmd >> my_name; x->set_label(my_name); } /*--------------------------------------------------------------------------*/ static void parse_ports(CS& cmd, COMPONENT* x) { assert(x); if (cmd >> '(') { int index = 0; while (cmd.is_alnum()) { unsigned here = cmd.cursor(); try{ std::string value; cmd >> value; x->set_port_by_index(index++, value); }catch (Exception_Too_Many& e) {untested(); cmd.warn(bDANGER, here, e.message()); } } cmd >> ')'; }else{ unsigned here = cmd.cursor(); OPT::language->find_type_in_string(cmd); unsigned stop = cmd.cursor(); cmd.reset(here); int index = 0; while (cmd.cursor() < stop) { here = cmd.cursor(); try{ std::string value; cmd >> value; x->set_port_by_index(index++, value); }catch (Exception_Too_Many& e) {untested(); cmd.warn(bDANGER, here, e.message()); } } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_COMMENT* LANG_SPECTRE::parse_comment(CS& cmd, DEV_COMMENT* x) { assert(x); x->set(cmd.fullstring()); return x; } /*--------------------------------------------------------------------------*/ DEV_DOT* LANG_SPECTRE::parse_command(CS& cmd, DEV_DOT* x) { assert(x); x->set(cmd.fullstring()); CARD_LIST* scope = (x->owner()) ? x->owner()->subckt() : &CARD_LIST::card_list; cmd.reset().skipbl(); if ((cmd >> "model |simulator |parameters |subckt ")) { cmd.reset(); CMD::cmdproc(cmd, scope); }else{ std::string label; cmd >> label; if (label != "-") { unsigned here = cmd.cursor(); std::string command; cmd >> command; cmd.reset(here); std::string file_name = label + '.' + command; std::string s = cmd.tail() + " > " + file_name; CS augmented_cmd(CS::_STRING, s); CMD::cmdproc(augmented_cmd, scope); }else{ CMD::cmdproc(cmd, scope); } } delete x; return NULL; } /*--------------------------------------------------------------------------*/ MODEL_CARD* LANG_SPECTRE::parse_paramset(CS& cmd, MODEL_CARD* x) { assert(x); cmd.reset().skipbl(); cmd >> "model "; parse_label(cmd, x); parse_type(cmd, x); parse_args(cmd, x); cmd.check(bWARNING, "what's this?"); return x; } /*--------------------------------------------------------------------------*/ MODEL_SUBCKT* LANG_SPECTRE::parse_module(CS& cmd, MODEL_SUBCKT* x) { assert(x); // header cmd.reset().skipbl(); cmd >> "subckt "; parse_label(cmd, x); parse_ports(cmd, x); // body for (;;) { cmd.get_line("spectre-subckt>"); if (cmd >> "ends ") { break; }else{ new__instance(cmd, x, x->subckt()); } } return x; } /*--------------------------------------------------------------------------*/ COMPONENT* LANG_SPECTRE::parse_instance(CS& cmd, COMPONENT* x) { cmd.reset(); parse_label(cmd, x); parse_ports(cmd, x); parse_type(cmd, x); parse_args(cmd, x); cmd.check(bWARNING, "what's this?"); return x; } /*--------------------------------------------------------------------------*/ std::string LANG_SPECTRE::find_type_in_string(CS& cmd) { // known to be not always correct cmd.reset().skipbl(); unsigned here = 0; std::string type; if ((cmd >> "*|//")) {itested(); assert(here == 0); type = "dev_comment"; }else if ((cmd >> "model |simulator |parameters |subckt ")) { // type is first, it's a control statement type = cmd.trimmed_last_match(); }else if (cmd.reset().skiparg().match1("(") && cmd.scan(")")) { // node list surrounded by parens // type follows here = cmd.cursor(); cmd.reset(here); cmd >> type; }else if (cmd.reset().scan("=")) {itested(); // back up two, by starting over cmd.reset().skiparg(); unsigned here1 = cmd.cursor(); cmd.skiparg(); unsigned here2 = cmd.cursor(); cmd.skiparg(); unsigned here3 = cmd.cursor(); while (here2 != here3 && !cmd.match1('=')) { cmd.skiparg(); here1 = here2; here2 = here3; here3 = cmd.cursor(); } here = here1; cmd.reset(here); cmd >> type; }else{ // type is second cmd.reset().skiparg(); here = cmd.cursor(); cmd.reset(here); cmd >> type; } cmd.reset(here); return type; } /*--------------------------------------------------------------------------*/ void LANG_SPECTRE::parse_top_item(CS& cmd, CARD_LIST* Scope) { cmd.get_line("gnucap-spectre>"); new__instance(cmd, NULL, Scope); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void LANG_SPECTRE::print_args(OMSTREAM& o, const CARD* x) { assert(x); o << ' '; if (x->use_obsolete_callback_print()) { x->print_args_obsolete_callback(o, this); //BUG//callback// }else{ for (int ii = x->param_count() - 1; ii >= 0; --ii) { if (x->param_is_printable(ii)) { std::string arg = " " + x->param_name(ii) + "=" + x->param_value(ii); o << arg; }else{ } } } } /*--------------------------------------------------------------------------*/ static void print_type(OMSTREAM& o, const COMPONENT* x) { assert(x); o << ' ' << x->dev_type(); } /*--------------------------------------------------------------------------*/ static void print_label(OMSTREAM& o, const COMPONENT* x) { assert(x); o << x->short_label(); } /*--------------------------------------------------------------------------*/ static void print_ports(OMSTREAM& o, const COMPONENT* x) { assert(x); o << " ("; std::string sep = ""; for (int ii = 0; x->port_exists(ii); ++ii) { o << sep << x->port_value(ii); sep = " "; } for (int ii = 0; x->current_port_exists(ii); ++ii) { o << sep << x->current_port_value(ii); sep = " "; } o << ")"; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void LANG_SPECTRE::print_paramset(OMSTREAM& o, const MODEL_CARD* x) { assert(x); o << "model " << x->short_label() << ' ' << x->dev_type() << ' '; print_args(o, x); o << "\n\n"; } /*--------------------------------------------------------------------------*/ void LANG_SPECTRE::print_module(OMSTREAM& o, const MODEL_SUBCKT* x) { assert(x); assert(x->subckt()); o << "subckt " << x->short_label(); print_ports(o, x); o << "\n"; for (CARD_LIST::const_iterator ci = x->subckt()->begin(); ci != x->subckt()->end(); ++ci) { print_item(o, *ci); } o << "ends " << x->short_label() << "\n\n"; } /*--------------------------------------------------------------------------*/ void LANG_SPECTRE::print_instance(OMSTREAM& o, const COMPONENT* x) { print_label(o, x); print_ports(o, x); print_type(o, x); print_args(o, x); o << "\n"; } /*--------------------------------------------------------------------------*/ void LANG_SPECTRE::print_comment(OMSTREAM& o, const DEV_COMMENT* x) { assert(x); o << x->comment() << '\n'; } /*--------------------------------------------------------------------------*/ void LANG_SPECTRE::print_command(OMSTREAM& o, const DEV_DOT* x) { assert(x); o << x->s() << '\n'; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ class CMD_MODEL : public CMD { void do_it(CS& cmd, CARD_LIST* Scope) { // already got "model" std::string my_name, base_name; cmd >> my_name; unsigned here = cmd.cursor(); cmd >> base_name; //const MODEL_CARD* p = model_dispatcher[base_name]; const CARD* p = lang_spectre.find_proto(base_name, NULL); if (p) { MODEL_CARD* new_card = dynamic_cast(p->clone()); if (exists(new_card)) { assert(!new_card->owner()); lang_spectre.parse_paramset(cmd, new_card); Scope->push_back(new_card); }else{ //BUG// memory leak cmd.warn(bDANGER, here, "model: base has incorrect type"); } }else{ cmd.warn(bDANGER, here, "model: no match"); } } } p1; DISPATCHER::INSTALL d1(&command_dispatcher, "model", &p1); /*--------------------------------------------------------------------------*/ class CMD_SUBCKT : public CMD { void do_it(CS& cmd, CARD_LIST* Scope) { MODEL_SUBCKT* new_module = new MODEL_SUBCKT; assert(new_module); assert(!new_module->owner()); assert(new_module->subckt()); assert(new_module->subckt()->is_empty()); lang_spectre.parse_module(cmd, new_module); Scope->push_back(new_module); } } p2; DISPATCHER::INSTALL d2(&command_dispatcher, "subckt", &p2); /*--------------------------------------------------------------------------*/ class CMD_SIMULATOR : public CMD { void do_it(CS& cmd, CARD_LIST* Scope) { command("options " + cmd.tail(), Scope); } } p3; DISPATCHER::INSTALL d3(&command_dispatcher, "simulator", &p3); /*--------------------------------------------------------------------------*/ class CMD_SPECTRE : public CMD { public: void do_it(CS&, CARD_LIST* Scope) { command("options lang=spectre", Scope); } } p8; DISPATCHER::INSTALL d8(&command_dispatcher, "spectre", &p8); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/lang_spice.cc�����������������������������������������������������������������������������������0000664�0000000�0000000�00000100152�11454012162�0014253�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: lang_spice.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2006 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script 2007.07.13 #include "u_status.h" #include "c_comand.h" #include "d_dot.h" #include "d_coment.h" #include "d_subckt.h" #include "u_lang.h" // header hack #include "d_logic.h" #include "bm.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class LANG_SPICE_BASE : public LANGUAGE { public: enum EOB {NO_EXIT_ON_BLANK, EXIT_ON_BLANK}; public: // override virtual, used by callback std::string arg_front()const {return " ";} std::string arg_mid()const {return "=";} std::string arg_back()const {return "";} public: // override virtual, called by commands DEV_COMMENT* parse_comment(CS&, DEV_COMMENT*); DEV_DOT* parse_command(CS&, DEV_DOT*); MODEL_CARD* parse_paramset(CS&, MODEL_CARD*); MODEL_SUBCKT* parse_module(CS&, MODEL_SUBCKT*); COMPONENT* parse_instance(CS&, COMPONENT*); std::string find_type_in_string(CS&); public: // "local?", called by own commands void parse_module_body(CS&, MODEL_SUBCKT*, CARD_LIST*, const std::string&, EOB, const std::string&); private: // local void parse_type(CS&, CARD*); void parse_args(CS&, CARD*); void parse_label(CS&, CARD*); void parse_ports(CS&, COMPONENT*, int minnodes, int start, int num_nodes, bool all_new); private: // compatibility hacks void parse_element_using_obsolete_callback(CS&, COMPONENT*); void parse_logic_using_obsolete_callback(CS&, COMPONENT*); private: // override virtual, called by print_item void print_paramset(OMSTREAM&, const MODEL_CARD*); void print_module(OMSTREAM&, const MODEL_SUBCKT*); void print_instance(OMSTREAM&, const COMPONENT*); void print_comment(OMSTREAM&, const DEV_COMMENT*); void print_command(OMSTREAM&, const DEV_DOT*); private: // local void print_args(OMSTREAM&, const MODEL_CARD*); void print_type(OMSTREAM&, const COMPONENT*); void print_args(OMSTREAM&, const COMPONENT*); void print_label(OMSTREAM&, const COMPONENT*); void print_ports(OMSTREAM&, const COMPONENT*); }; /*--------------------------------------------------------------------------*/ class LANG_SPICE : public LANG_SPICE_BASE { public: std::string name()const {return "spice";} bool case_insensitive()const {return true;} UNITS units()const {return uSPICE;} void parse_top_item(CS&, CARD_LIST*); } lang_spice; DISPATCHER::INSTALL ds(&language_dispatcher, lang_spice.name(), &lang_spice); /*--------------------------------------------------------------------------*/ class LANG_ACS : public LANG_SPICE_BASE { public: std::string name()const {return "acs";} bool case_insensitive()const {return true;} UNITS units()const {return uSPICE;} } lang_acs; DISPATCHER::INSTALL da(&language_dispatcher, lang_acs.name(), &lang_acs); /*--------------------------------------------------------------------------*/ DEV_COMMENT p0; DISPATCHER::INSTALL d0(&device_dispatcher, ";|#|*|'|\"|dev_comment", &p0); /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ static void skip_pre_stuff(CS& cmd) { cmd.skipbl(); while (cmd.umatch(CKT_PROMPT)) {untested(); /* skip any number of copies of the prompt */ } cmd.umatch(ANTI_COMMENT); /* skip mark so spice ignores but gnucap reads */ } /*--------------------------------------------------------------------------*/ /* count_ports: figure out how many ports * returns the number of ports * side effect: "CS" is advanced to past the ports, ready for what follows */ static int count_ports(CS& cmd, int maxnodes, int minnodes, int leave_tail, int start) { assert(start < maxnodes); assert(minnodes <= maxnodes); int num_nodes = 0; std::vector spots; int paren = cmd.skip1b('('); int i = start; // loop over the tokens to try to guess where the nodes end // and other stuff begins spots.push_back(cmd.cursor()); for (;;) { ++i; //cmd.skiparg(); std::string node_name; cmd >> node_name; spots.push_back(cmd.cursor()); if (paren && cmd.skip1b(')')) { num_nodes = i; break; }else if (cmd.is_end()) { // found the end, no '=' if (i <= minnodes) { num_nodes = i; }else if (i <= minnodes + leave_tail) { num_nodes = minnodes; }else if (i <= maxnodes + leave_tail) { num_nodes = i - leave_tail; }else{ num_nodes = maxnodes; } break; }else if (cmd.skip1b("({})")) { // found '(', it's past the end of nodes if (i > maxnodes + leave_tail) { num_nodes = maxnodes; }else{ num_nodes = i - leave_tail; } break; }else if (cmd.skip1b('=')) { // found '=', it's past the end of nodes if (i > maxnodes + leave_tail + 1) { num_nodes = maxnodes; }else{ num_nodes = i - leave_tail - 1; } break; }else{ } } if (num_nodes < start) { cmd.reset(spots.back()); throw Exception("what's this?"); }else{ } cmd.reset(spots[static_cast(num_nodes-start)]); //cmd.warn(bDANGER, "past-nodes?"); //BUG// assert fails on current controlled sources with (node node dev) syntax // it's ok with (node node) dev syntax or node node dev syntax assert(num_nodes <= maxnodes); return num_nodes; } /*--------------------------------------------------------------------------*/ /* parse_ports: parse circuit connections from input string * fills in the rest of the array with 0 * returns the number of nodes actually read * The purpose of this complexity is to handle the variants of Spice formats, * which might have keys between nodes, * an unknown number of nodes with unknown number of args and no delimeters. * Consider: X1 a b c d e f g h i j k * Clearly (?) a,b,c,d,e are nodes, f is a subckt name, the rest are args. * But how do you know? * * Args: * maxnodes: the maximum number of port nodes to parse. * Stop here, even if it seems there should be more. * * minnodes: the minimum number of port nodes to parse. * It is an error if there are fewer than this. * * leave_tail: The number of arguments that are not nodes, * and don't have equal signs, following. * It is an aid to distinguishing the nodes from things that follow. * minnodes wins over leave_tail, but leave_tail wins over maxnodes. * The above example would need leave_tail=6 to parse correctly. * This one: X1 a b c d e f g=h i=j k * where a,b,c,d,e are nodes, f is a subckt or model identifier * would parse correctly with leave_tail=1. * Usual values for leave_tail are 0 or 1. * * start: start at this number, used for continuing after HSPICE kluge. * Other than that, the only useful value for start is 0. * * all_new: All node names must be new (not already defined) and unique. * This is used for the header line in .subckt, which starts clean. * The main benefit is to reject duplicates. */ void LANG_SPICE_BASE::parse_ports(CS& cmd, COMPONENT* x, int minnodes, int start, int num_nodes, bool all_new) { assert(x); int paren = cmd.skip1b('('); int ii = start; unsigned here1 = cmd.cursor(); try{ for (;;) { here1 = cmd.cursor(); if (paren && cmd.skip1b(')')) { --paren; break; // done. have closing paren. }else if (ii >= num_nodes) { break; // done. have maxnodes. }else if (!cmd.more()) {untested(); break; // done. premature end of line. }else if (OPT::keys_between_nodes && (cmd.umatch("poly ") || cmd.umatch("pwl ") || cmd.umatch("vccap ") || cmd.umatch("vcg ") || cmd.umatch("vcr ")) ) { cmd.reset(here1); break; // done, found reserved word between nodes }else{ //---------------------- unsigned here = cmd.cursor(); std::string node_name; cmd >> node_name; if (cmd.stuck(&here)) {itested(); // didn't move, probably a terminator. throw Exception("bad node name"); }else{ // legal node name, store it. x->set_port_by_index(ii, node_name); } //---------------------- if (!(x->node_is_connected(ii))) {untested(); break; // illegal node name, might be proper exit. }else{ if (all_new) { if (x->node_is_grounded(ii)) {untested(); cmd.warn(bDANGER, here1, "node 0 not allowed here"); }else{ } }else{ } ++ii; } } } }catch (Exception& e) {itested(); cmd.warn(bDANGER, here1, e.message()); } if (ii < minnodes) {itested(); cmd.warn(bDANGER, "need " + to_string(minnodes-ii) +" more nodes"); }else{ } if (paren != 0) {untested(); cmd.warn(bWARNING, "need )"); }else{ } //assert(x->_net_nodes == ii); // ground unused input nodes for (int iii = ii; iii < minnodes; ++iii) {itested(); x->set_port_to_ground(iii); } //assert(x->_net_nodes >= ii); } /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::parse_element_using_obsolete_callback(CS& cmd, COMPONENT* x) { assert(x); ELEMENT* xx = dynamic_cast(x); assert(xx); { unsigned here = cmd.cursor(); int stop_nodes = x->max_nodes() - x->num_current_ports(); int num_nodes = count_ports(cmd, stop_nodes, 0, 0, 0); // max min tail already_got cmd.reset(here); parse_ports(cmd, x, 0, 0, num_nodes, false); // min already_got } int gotnodes = x->_net_nodes; COMMON_COMPONENT* c = NULL; if (gotnodes < x->min_nodes()) { // HSPICE compatibility kluge. // The device type or function type could be stuck between the nodes. xx->skip_dev_type(cmd); // (redundant) c = EVAL_BM_ACTION_BASE::parse_func_type(cmd); { unsigned here = cmd.cursor(); int num_nodes = count_ports(cmd, x->max_nodes(), x->min_nodes(), 0, gotnodes); cmd.reset(here); parse_ports(cmd, x, x->min_nodes(), gotnodes, num_nodes, false); } }else{ // Normal mode. nodes first, then data. } if (!c) { xx->skip_dev_type(cmd); // (redundant) c = bm_dispatcher.clone("eval_bm_cond"); }else{ } if (!c) { c = bm_dispatcher.clone("eval_bm_value"); }else{ } assert(c); // we have a blank common of the most general type // (or HSPICE kluge) // let it continue parsing unsigned here = cmd.cursor(); c->parse_common_obsolete_callback(cmd); //BUG//callback if (cmd.stuck(&here)) {untested(); cmd.warn(bDANGER, "needs a value"); }else{ } // At this point, there is ALWAYS a common "c", which may have more // commons attached to it. Try to reduce its complexity. // "c->deflate()" may return "c" or some simplification of "c". COMMON_COMPONENT* dc = c->deflate(); // dc == deflated_common // It might be just "c". // It might be something else that is simpler but equivalent. if (dc->is_trivial()) { assert(dynamic_cast(dc)); // If it is a simple value, don't use a common. // Just store the value directly. x->obsolete_move_parameters_from_common(dc); delete c; }else{ x->attach_common(dc); if (dc != c) { delete c; }else{ } } cmd.check(bDANGER, "what's this?"); } /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::parse_logic_using_obsolete_callback(CS& cmd, COMPONENT* x) { assert(x); { unsigned here = cmd.cursor(); int num_nodes = count_ports(cmd, x->max_nodes(), x->min_nodes(), x->tail_size(), 0/*start*/); cmd.reset(here); parse_ports(cmd, x, x->min_nodes(), 0/*start*/, num_nodes, false); } int incount = x->net_nodes() - x->min_nodes() + 1; assert(incount > 0); std::string modelname = cmd.ctos(TOKENTERM); COMMON_LOGIC* common = 0; if (cmd.umatch("and " )) {untested();common = new LOGIC_AND;} else if (cmd.umatch("nand ")) {common = new LOGIC_NAND;} else if (cmd.umatch("or " )) {untested();common = new LOGIC_OR;} else if (cmd.umatch("nor " )) {common = new LOGIC_NOR;} else if (cmd.umatch("xor " )) {untested();common = new LOGIC_XOR;} else if (cmd.umatch("xnor ")) {untested();common = new LOGIC_XNOR;} else if (cmd.umatch("inv " )) {common = new LOGIC_INV;} else {itested(); cmd.warn(bWARNING,"need and,nand,or,nor,xor,xnor,inv"); common=new LOGIC_NONE; } assert(common); common->incount = incount; common->set_modelname(modelname); x->attach_common(common); } /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::parse_type(CS& cmd, CARD* x) { assert(x); std::string new_type; cmd >> new_type; x->set_dev_type(new_type); } /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::parse_args(CS& cmd, CARD* x) { assert(x); COMPONENT* xx = dynamic_cast(x); cmd >> "params:"; // optional, skip it. if (!x->use_obsolete_callback_parse()) { int paren = cmd.skip1b('('); if (xx && cmd.is_float()) { // simple unnamed value std::string value; cmd >> value; x->set_param_by_name(xx->value_name(), value); }else if (cmd.match1("'{")) { // quoted unnamed value std::string value; cmd >> value; // strips off the quotes value = '{' + value + '}'; // put them back x->set_param_by_name(xx->value_name(), value); }else{ // only name=value pairs } unsigned here = cmd.cursor(); for (int i=0; ; ++i) { if (paren && cmd.skip1b(')')) { break; }else if (!cmd.more()) { break; }else{ std::string Name = cmd.ctos("=", "", ""); cmd >> '='; std::string value = cmd.ctos(",=;)", "\"'{(", "\"'})"); unsigned there = here; if (cmd.stuck(&here)) {untested(); break; }else{ try{ if (value == "") { cmd.warn(bDANGER, there, x->long_label() + ": " + Name + " has no value?"); }else{ } x->set_param_by_name(Name, value); }catch (Exception_No_Match&) {itested(); cmd.warn(bDANGER, there, x->long_label() + ": bad parameter " + Name + " ignored"); } } } } }else if (MODEL_CARD* pp = dynamic_cast(x)) { // used only for "table" int paren = cmd.skip1b('('); bool in_error = false; for (;;) { unsigned here = cmd.cursor(); pp->parse_params_obsolete_callback(cmd); //BUG//callback// if (!cmd.more()) { break; }else if (paren && cmd.skip1b(')')) {untested(); break; }else if (cmd.stuck(&here)) {untested(); if (in_error) {untested(); // so you don't get two errors on name = value. cmd.skiparg(); in_error = false; }else{untested(); cmd.warn(bDANGER, "bad paramerter -- ignored"); cmd.skiparg().skip1b("="); in_error = true; } }else{ in_error = false; } } }else{untested(); // using obsolete_callback } } /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::parse_label(CS& cmd, CARD* x) { assert(x); std::string my_name; cmd >> my_name; x->set_label(my_name); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_COMMENT* LANG_SPICE_BASE::parse_comment(CS& cmd, DEV_COMMENT* x) { assert(x); x->set(cmd.fullstring()); return x; } /*--------------------------------------------------------------------------*/ DEV_DOT* LANG_SPICE_BASE::parse_command(CS& cmd, DEV_DOT* x) { assert(x); x->set(cmd.fullstring()); CARD_LIST* scope = (x->owner()) ? x->owner()->subckt() : &CARD_LIST::card_list; cmd.reset(); skip_pre_stuff(cmd); unsigned here = cmd.cursor(); std::string s; cmd >> s; cmd.reset(here); if (!command_dispatcher[s]) { cmd.skip(); ++here; }else{ } CMD::cmdproc(cmd, scope); delete x; return NULL; } /*--------------------------------------------------------------------------*/ MODEL_CARD* LANG_SPICE_BASE::parse_paramset(CS& cmd, MODEL_CARD* x) { assert(x); cmd.reset(); cmd >> ".model "; parse_label(cmd, x); parse_type(cmd, x); parse_args(cmd, x); cmd.check(bWARNING, "what's this?"); return x; } /*--------------------------------------------------------------------------*/ MODEL_SUBCKT* LANG_SPICE_BASE::parse_module(CS& cmd, MODEL_SUBCKT* x) { assert(x); // header cmd.reset(); (cmd >> ".subckt |.macro "); parse_label(cmd, x); { unsigned here = cmd.cursor(); int num_nodes = count_ports(cmd, x->max_nodes(), x->min_nodes(), 0/*no unnamed par*/, 0/*start*/); cmd.reset(here); parse_ports(cmd, x, x->min_nodes(), 0/*start*/, num_nodes, true/*all new*/); } x->subckt()->params()->parse(cmd); // body parse_module_body(cmd, x, x->subckt(), name() + "-subckt>", NO_EXIT_ON_BLANK, ".ends |.eom "); return x; } /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::parse_module_body(CS& cmd, MODEL_SUBCKT* x, CARD_LIST* Scope, const std::string& prompt, EOB exit_on_blank, const std::string& exit_key) { try { for (;;) { cmd.get_line(prompt); if ((exit_on_blank==EXIT_ON_BLANK && cmd.is_end()) || cmd.umatch(exit_key)) { break; }else{ skip_pre_stuff(cmd); new__instance(cmd, x, Scope); } } }catch (Exception_End_Of_Input& e) { } } /*--------------------------------------------------------------------------*/ COMPONENT* LANG_SPICE_BASE::parse_instance(CS& cmd, COMPONENT* x) { try { assert(x); cmd.reset().umatch(ANTI_COMMENT); // ACS dot type specifier if (cmd.skip1b('.')) { parse_type(cmd, x); }else{ } parse_label(cmd, x); if (x->use_obsolete_callback_parse()) { parse_element_using_obsolete_callback(cmd, x); }else if (DEV_LOGIC* xx = dynamic_cast(x)) { parse_logic_using_obsolete_callback(cmd, xx); }else{ { unsigned here = cmd.cursor(); int num_nodes = count_ports(cmd, x->max_nodes(), x->min_nodes(), x->tail_size(), 0); cmd.reset(here); parse_ports(cmd, x, x->min_nodes(), 0/*start*/, num_nodes, false); } if (x->print_type_in_spice()) { parse_type(cmd, x); }else{ } parse_args(cmd, x); } }catch (Exception& e) { cmd.warn(bDANGER, e.message()); } return x; } /*--------------------------------------------------------------------------*/ std::string LANG_SPICE_BASE::find_type_in_string(CS& cmd) { cmd.umatch(ANTI_COMMENT); /* skip mark so spice ignores but gnucap reads */ unsigned here = cmd.cursor(); std::string s; char id_letter = cmd.peek(); if (OPT::case_insensitive) { id_letter = static_cast(toupper(id_letter)); }else{ } switch (id_letter) { case '\0':untested(); s = ""; break; case '.': cmd >> s; cmd.reset(here); if (!command_dispatcher[s]) { cmd.skip(); ++here; s = s.substr(1); }else{ } break; case 'G': here = cmd.cursor(); if (cmd.scan("vccap |vcg |vcr |vccs ")) { s = cmd.trimmed_last_match(); }else{ s = "G"; } break; default: s = id_letter; break; } cmd.reset(here); return s; } /*--------------------------------------------------------------------------*/ void LANG_SPICE::parse_top_item(CS& cmd, CARD_LIST* Scope) { if (0 && cmd.is_file() && cmd.is_first_read() && (Scope == &CARD_LIST::card_list) && (Scope->is_empty()) && (head == "'")) {untested(); //BUG// ugly hack cmd.get_line("gnucap-spice-title>"); head = cmd.fullstring(); IO::mstdout << head << '\n'; }else{itested(); cmd.get_line("gnucap-spice>"); new__instance(cmd, NULL, Scope); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ static char fix_case(char c) { return ((OPT::case_insensitive) ? (static_cast(tolower(c))) : (c)); } /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::print_paramset(OMSTREAM& o, const MODEL_CARD* x) { assert(x); o << ".model " << x->short_label() << ' ' << x->dev_type() << " ("; print_args(o, x); o << ")\n"; } /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::print_module(OMSTREAM& o, const MODEL_SUBCKT* x) { assert(x); assert(x->subckt()); o << ".subckt " << x->short_label(); print_ports(o, x); o << '\n'; for (CARD_LIST::const_iterator ci = x->subckt()->begin(); ci != x->subckt()->end(); ++ci) { print_item(o, *ci); } o << ".ends " << x->short_label() << "\n"; } /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::print_instance(OMSTREAM& o, const COMPONENT* x) { print_label(o, x); print_ports(o, x); print_type(o, x); print_args(o, x); o << '\n'; } /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::print_comment(OMSTREAM& o, const DEV_COMMENT* x) { assert(x); if (x->comment()[1] != '+') { o << x->comment() << '\n'; }else{ } // Suppress printing of comment lines starting with "*+". // These are generated as a way to display calculated values. } /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::print_command(OMSTREAM& o, const DEV_DOT* x) { assert(x); o << x->s() << '\n'; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::print_args(OMSTREAM& o, const MODEL_CARD* x) { assert(x); if (x->use_obsolete_callback_print()) { x->print_args_obsolete_callback(o, this); //BUG//callback// }else{ for (int ii = x->param_count() - 1; ii >= x->param_count_dont_print(); --ii) { if (x->param_is_printable(ii)) { std::string arg = " " + x->param_name(ii) + "=" + x->param_value(ii); o << arg; }else{ } } } } /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::print_type(OMSTREAM& o, const COMPONENT* x) { assert(x); if (x->print_type_in_spice()) { o << " " << x->dev_type(); }else if (fix_case(x->short_label()[0]) != fix_case(x->id_letter())) {itested(); o << " " << x->dev_type(); }else{ // don't print type } } /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::print_args(OMSTREAM& o, const COMPONENT* x) { assert(x); o << ' '; if (x->use_obsolete_callback_print()) { x->print_args_obsolete_callback(o, this); //BUG//callback// }else{ for (int ii = x->param_count() - 1; ii >= x->param_count_dont_print(); --ii) { if (x->param_is_printable(ii)) { if ((ii != x->param_count() - 1) || (x->param_name(ii) != x->value_name())) { // skip name if plain value o << " " << x->param_name(ii) << "="; }else{ } o << x->param_value(ii); }else{ } } } } /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::print_label(OMSTREAM& o, const COMPONENT* x) { assert(x); std::string label = x->short_label(); o << label; } /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::print_ports(OMSTREAM& o, const COMPONENT* x) { assert(x); o << " ( "; std::string sep = ""; for (int ii = 0; x->port_exists(ii); ++ii) { o << sep << x->port_value(ii); sep = " "; } for (int ii = 0; x->current_port_exists(ii); ++ii) { o << sep << x->current_port_value(ii); sep = " "; } o << " )"; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ class CMD_MODEL : public CMD { void do_it(CS& cmd, CARD_LIST* Scope) { // already got "model" std::string my_name, base_name; cmd >> my_name; unsigned here1 = cmd.cursor(); cmd >> base_name; // "level" kluge .... // if there is a "level" keyword, with integer argument, // tack that onto the given modelname and look for that cmd.skip1b('('); int level = 0; { unsigned here = cmd.cursor(); scan_get(cmd, "level ", &level); if (!cmd.stuck(&here)) { char buf[20]; sprintf(buf, "%u", level); base_name += buf; }else{ } } const MODEL_CARD* p = model_dispatcher[base_name]; if (p) { MODEL_CARD* new_card = dynamic_cast(p->clone()); if (exists(new_card)) { assert(!new_card->owner()); lang_spice.parse_paramset(cmd, new_card); Scope->push_back(new_card); }else{untested(); cmd.warn(bDANGER, here1, "model: base has incorrect type"); } }else{ cmd.warn(bDANGER, here1, "model: \"" + base_name + "\" no match"); } } } p1; DISPATCHER::INSTALL d1(&command_dispatcher, ".model", &p1); /*--------------------------------------------------------------------------*/ class CMD_SUBCKT : public CMD { void do_it(CS& cmd, CARD_LIST* Scope) { MODEL_SUBCKT* new_module = new MODEL_SUBCKT; assert(new_module); assert(!new_module->owner()); assert(new_module->subckt()); assert(new_module->subckt()->is_empty()); lang_spice.parse_module(cmd, new_module); Scope->push_back(new_module); } } p2; DISPATCHER::INSTALL d2(&command_dispatcher, ".subckt|.macro", &p2); /*--------------------------------------------------------------------------*/ enum Skip_Header {NO_HEADER, SKIP_HEADER}; /*--------------------------------------------------------------------------*/ /* getmerge: actually do the work for "get", "merge", etc. */ static void getmerge(CS& cmd, Skip_Header skip_header, CARD_LIST* Scope) { ::status.get.reset().start(); assert(Scope); std::string file_name, section_name; cmd >> file_name; bool echoon = false; /* echo on/off flag (echo as read from file) */ bool liston = false; /* list on/off flag (list actual values) */ bool quiet = false; /* don't echo title */ unsigned here = cmd.cursor(); do{ ONE_OF || Get(cmd, "echo", &echoon) || Get(cmd, "list", &liston) || Get(cmd, "quiet", &quiet) || Get(cmd, "section", §ion_name) ; }while (cmd.more() && !cmd.stuck(&here)); if (cmd.more()) { cmd >> section_name; }else{ } cmd.check(bWARNING, "need section, echo, list, or quiet"); CS file(CS::_INC_FILE, file_name); if (skip_header) { // get and store the header line file.get_line(">>>>"); head = file.fullstring(); if (!quiet) { IO::mstdout << head << '\n'; }else{untested(); } }else{ } if (section_name == "") { lang_spice.parse_module_body(file, NULL, Scope, ">>>>", lang_spice.NO_EXIT_ON_BLANK, ".end "); }else{ try { for (;;) { file.get_line("lib " + section_name + '>'); if (file.umatch(".lib " + section_name + ' ')) { lang_spice.parse_module_body(file, NULL, Scope, section_name, lang_spice.NO_EXIT_ON_BLANK, ".endl {" + section_name + "}"); }else{ // skip it } } }catch (Exception_End_Of_Input& e) { } } ::status.get.stop(); } /*--------------------------------------------------------------------------*/ /* cmd_lib: lib command */ class CMD_LIB : public CMD { public: void do_it(CS& cmd, CARD_LIST* Scope) { unsigned here = cmd.cursor(); std::string section_name, more_stuff; cmd >> section_name >> more_stuff; if (more_stuff != "") { cmd.reset(here); getmerge(cmd, NO_HEADER, Scope); }else{ for (;;) { cmd.get_line(section_name + '>'); if (cmd.umatch(".endl {" + section_name + "}")) { break; }else{ // skip it } } } } } p33; DISPATCHER::INSTALL d33(&command_dispatcher, ".lib|lib", &p33); /*--------------------------------------------------------------------------*/ /* cmd_include: include command * as get or run, but do not clear first, inherit the run-mode. */ class CMD_INCLUDE : public CMD { public: void do_it(CS& cmd, CARD_LIST* Scope) { getmerge(cmd, NO_HEADER, Scope); } } p3; DISPATCHER::INSTALL d3(&command_dispatcher, ".include", &p3); /*--------------------------------------------------------------------------*/ /* cmd_merge: merge command * as get, but do not clear first */ class CMD_MERGE : public CMD { public: void do_it(CS& cmd, CARD_LIST* Scope) {untested(); SET_RUN_MODE xx(rPRESET); getmerge(cmd, NO_HEADER, Scope); } } p4; DISPATCHER::INSTALL d4(&command_dispatcher, ".merge|merge", &p4); /*--------------------------------------------------------------------------*/ /* cmd_run: "<" and "<<" commands * run in batch mode. Spice format. * "<<" clears old circuit first, "<" does not * get circuit from file, execute dot cards in sequence */ class CMD_RUN : public CMD { public: void do_it(CS& cmd, CARD_LIST* Scope) { while (cmd.match1('<')) {untested(); command("clear", Scope); cmd.skip(); cmd.skipbl(); } SET_RUN_MODE xx(rSCRIPT); getmerge(cmd, SKIP_HEADER, Scope); } } p5; DISPATCHER::INSTALL d5(&command_dispatcher, "<", &p5); /*--------------------------------------------------------------------------*/ /* cmd_get: get command * get circuit from a file, after clearing the old one * preset, but do not execute "dot cards" */ class CMD_GET : public CMD { public: void do_it(CS& cmd, CARD_LIST* Scope) { SET_RUN_MODE xx(rPRESET); command("clear", Scope); getmerge(cmd, SKIP_HEADER, Scope); } } p6; DISPATCHER::INSTALL d6(&command_dispatcher, ".get|get", &p6); /*--------------------------------------------------------------------------*/ /* cmd_build: build command * get circuit description direct from keyboard (or stdin if redirected) * Command syntax: build * Bare command: add to end of list * If there is an arg: add before that element * null line exits this mode * preset, but do not execute "dot cards" */ class CMD_BUILD : public CMD { public: void do_it(CS& cmd, CARD_LIST* Scope) { SET_RUN_MODE xx(rPRESET); ::status.get.reset().start(); lang_spice.parse_module_body(cmd, NULL, Scope, ">", lang_spice.EXIT_ON_BLANK, ". "); ::status.get.stop(); } } p7; DISPATCHER::INSTALL d7(&command_dispatcher, ".build|build", &p7); /*--------------------------------------------------------------------------*/ class CMD_SPICE : public CMD { public: void do_it(CS&, CARD_LIST* Scope) { command("options lang=spice", Scope); } } p8; DISPATCHER::INSTALL d8(&command_dispatcher, "spice", &p8); /*--------------------------------------------------------------------------*/ class CMD_ACS : public CMD { public: void do_it(CS&, CARD_LIST* Scope) { command("options lang=acs", Scope); } } p9; DISPATCHER::INSTALL d9(&command_dispatcher, "acs", &p9); /*--------------------------------------------------------------------------*/ class CMD_ENDC : public CMD { public: void do_it(CS&, CARD_LIST* Scope) { if (OPT::language == &lang_acs) { command("options lang=spice", Scope); }else{ } } } p88; DISPATCHER::INSTALL d88(&command_dispatcher, ".endc", &p88); /*--------------------------------------------------------------------------*/ class CMD_CONTROL : public CMD { public: void do_it(CS&, CARD_LIST* Scope) { if (OPT::language == &lang_spice) { command("options lang=acs", Scope); }else{ } } } p99; DISPATCHER::INSTALL d99(&command_dispatcher, ".control", &p99); /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/lang_verilog.cc���������������������������������������������������������������������������������0000664�0000000�0000000�00000034403�11454012162�0014624�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: lang_verilog.cc,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*- * Copyright (C) 2007 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include "c_comand.h" #include "d_dot.h" #include "d_coment.h" #include "d_subckt.h" #include "e_model.h" #include "u_lang.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class LANG_VERILOG : public LANGUAGE { enum MODE {mDEFAULT, mPARAMSET} _mode; mutable int arg_count; enum {INACTIVE = -1}; public: LANG_VERILOG() : arg_count(INACTIVE) {} std::string name()const {return "verilog";} bool case_insensitive()const {return false;} UNITS units()const {return uSI;} public: // override virtual, used by callback std::string arg_front()const { switch (_mode) { case mPARAMSET: return " ."; break; case mDEFAULT: return (arg_count++ > 0) ? ", ." : "."; break; } unreachable(); return ""; } std::string arg_mid()const { switch (_mode) { case mPARAMSET: return "="; break; case mDEFAULT: return "("; break; } unreachable(); return ""; } std::string arg_back()const { switch (_mode) { case mPARAMSET: return ";"; break; case mDEFAULT: return ")"; break; } unreachable(); return ""; } public: // override virtual, called by commands void parse_top_item(CS&, CARD_LIST*); DEV_COMMENT* parse_comment(CS&, DEV_COMMENT*); DEV_DOT* parse_command(CS&, DEV_DOT*); MODEL_CARD* parse_paramset(CS&, MODEL_CARD*); MODEL_SUBCKT* parse_module(CS&, MODEL_SUBCKT*); COMPONENT* parse_instance(CS&, COMPONENT*); std::string find_type_in_string(CS&); private: // override virtual, called by print_item void print_paramset(OMSTREAM&, const MODEL_CARD*); void print_module(OMSTREAM&, const MODEL_SUBCKT*); void print_instance(OMSTREAM&, const COMPONENT*); void print_comment(OMSTREAM&, const DEV_COMMENT*); void print_command(OMSTREAM& o, const DEV_DOT* c); private: // local void print_args(OMSTREAM&, const MODEL_CARD*); void print_args(OMSTREAM&, const COMPONENT*); } lang_verilog; DISPATCHER::INSTALL d(&language_dispatcher, lang_verilog.name(), &lang_verilog); /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ static void parse_type(CS& cmd, CARD* x) { assert(x); std::string new_type; cmd >> new_type; x->set_dev_type(new_type); } /*--------------------------------------------------------------------------*/ static void parse_args_paramset(CS& cmd, MODEL_CARD* x) { assert(x); while (cmd >> '.') { unsigned here = cmd.cursor(); std::string name, value; try{ cmd >> name >> '=' >> value >> ';'; x->set_param_by_name(name, value); }catch (Exception_No_Match&) {untested(); cmd.warn(bDANGER, here, x->long_label() + ": bad parameter " + name + " ignored"); } } } /*--------------------------------------------------------------------------*/ static void parse_args_instance(CS& cmd, CARD* x) { assert(x); if (cmd >> "#(") { if (cmd.match1('.')) { // by name while (cmd >> '.') { unsigned here = cmd.cursor(); std::string name = cmd.ctos("(", "", ""); std::string value = cmd.ctos(",)", "(", ")"); cmd >> ','; try{ x->set_param_by_name(name, value); }catch (Exception_No_Match&) {untested(); cmd.warn(bDANGER, here, x->long_label() + ": bad parameter " + name + " ignored"); } } }else{ // by order int index = 1; while (cmd.is_alnum()) { unsigned here = cmd.cursor(); try{ std::string value = cmd.ctos(",)", "", ""); x->set_param_by_index(x->param_count() - index++, value, 0/*offset*/); }catch (Exception_Too_Many& e) {untested(); cmd.warn(bDANGER, here, e.message()); } } } cmd >> ')'; }else{ // no args } } /*--------------------------------------------------------------------------*/ static void parse_label(CS& cmd, CARD* x) { assert(x); std::string my_name; cmd >> my_name; x->set_label(my_name); } /*--------------------------------------------------------------------------*/ static void parse_ports(CS& cmd, COMPONENT* x) { assert(x); if (cmd >> '(') { if (cmd.is_alnum()) { // by order int index = 0; while (cmd.is_alnum()) { unsigned here = cmd.cursor(); try{ std::string value; cmd >> value; x->set_port_by_index(index++, value); }catch (Exception_Too_Many& e) {untested(); cmd.warn(bDANGER, here, e.message()); } } }else{ // by name while (cmd >> '.') { unsigned here = cmd.cursor(); try{ std::string name, value; cmd >> name >> '(' >> value >> ')' >> ','; x->set_port_by_name(name, value); }catch (Exception_No_Match&) {untested(); cmd.warn(bDANGER, here, "mismatch, ignored"); } } } cmd >> ')'; }else{untested(); cmd.warn(bDANGER, "'(' required"); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_COMMENT* LANG_VERILOG::parse_comment(CS& cmd, DEV_COMMENT* x) { assert(x); x->set(cmd.fullstring()); return x; } /*--------------------------------------------------------------------------*/ DEV_DOT* LANG_VERILOG::parse_command(CS& cmd, DEV_DOT* x) { assert(x); x->set(cmd.fullstring()); CARD_LIST* scope = (x->owner()) ? x->owner()->subckt() : &CARD_LIST::card_list; cmd.reset(); CMD::cmdproc(cmd, scope); delete x; return NULL; } /*--------------------------------------------------------------------------*/ /* "paramset" ";" * * * * * "endparamset" */ //BUG// no paramset_item_declaration, falls back to spice mode //BUG// must be on single line MODEL_CARD* LANG_VERILOG::parse_paramset(CS& cmd, MODEL_CARD* x) { assert(x); cmd.reset(); cmd >> "paramset "; parse_label(cmd, x); parse_type(cmd, x); cmd >> ';'; parse_args_paramset(cmd, x); cmd >> "endparamset "; cmd.check(bWARNING, "what's this?"); return x; } /*--------------------------------------------------------------------------*/ /* "module" "(" ")" ";" * * * "endmodule" */ //BUG// strictly one device per line MODEL_SUBCKT* LANG_VERILOG::parse_module(CS& cmd, MODEL_SUBCKT* x) { assert(x); // header cmd.reset(); (cmd >> "module |macromodule "); parse_label(cmd, x); parse_ports(cmd, x); cmd >> ';'; // body for (;;) { cmd.get_line("verilog-module>"); if (cmd >> "endmodule ") { break; }else{ new__instance(cmd, x, x->subckt()); } } return x; } /*--------------------------------------------------------------------------*/ COMPONENT* LANG_VERILOG::parse_instance(CS& cmd, COMPONENT* x) { cmd.reset(); parse_type(cmd, x); parse_args_instance(cmd, x); parse_label(cmd, x); parse_ports(cmd, x); cmd >> ';'; cmd.check(bWARNING, "what's this?"); return x; } /*--------------------------------------------------------------------------*/ std::string LANG_VERILOG::find_type_in_string(CS& cmd) { unsigned here = cmd.cursor(); std::string type; if ((cmd >> "//")) { assert(here == 0); type = "dev_comment"; }else{ cmd >> type; } cmd.reset(here); return type; } /*--------------------------------------------------------------------------*/ void LANG_VERILOG::parse_top_item(CS& cmd, CARD_LIST* Scope) { cmd.get_line("gnucap-verilog>"); new__instance(cmd, NULL, Scope); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void LANG_VERILOG::print_args(OMSTREAM& o, const MODEL_CARD* x) { assert(x); if (x->use_obsolete_callback_print()) { x->print_args_obsolete_callback(o, this); //BUG//callback// }else{ for (int ii = x->param_count() - 1; ii >= 0; --ii) { if (x->param_is_printable(ii)) { std::string arg = " ." + x->param_name(ii) + "=" + x->param_value(ii) + ";"; o << arg; }else{ } } } } /*--------------------------------------------------------------------------*/ void LANG_VERILOG::print_args(OMSTREAM& o, const COMPONENT* x) { assert(x); o << " #("; if (x->use_obsolete_callback_print()) { arg_count = 0; x->print_args_obsolete_callback(o, this); //BUG//callback// arg_count = INACTIVE; }else{ std::string sep = "."; for (int ii = x->param_count() - 1; ii >= 0; --ii) { if (x->param_is_printable(ii)) { o << sep << x->param_name(ii) << "(" << x->param_value(ii) << ")"; sep = ",."; }else{ } } } o << ") "; } /*--------------------------------------------------------------------------*/ static void print_type(OMSTREAM& o, const COMPONENT* x) { assert(x); o << x->dev_type(); } /*--------------------------------------------------------------------------*/ static void print_label(OMSTREAM& o, const COMPONENT* x) { assert(x); o << x->short_label(); } /*--------------------------------------------------------------------------*/ static void print_ports_long(OMSTREAM& o, const COMPONENT* x) { // print in long form ... .name(value) assert(x); o << " ("; std::string sep = "."; for (int ii = 0; x->port_exists(ii); ++ii) { o << sep << x->port_name(ii) << '(' << x->port_value(ii) << ')'; sep = ",."; } for (int ii = 0; x->current_port_exists(ii); ++ii) { o << sep << x->current_port_name(ii) << '(' << x->current_port_value(ii) << ')'; sep = ",."; } o << ")"; } /*--------------------------------------------------------------------------*/ static void print_ports_short(OMSTREAM& o, const COMPONENT* x) { // print in short form ... value only assert(x); o << " ("; std::string sep = ""; for (int ii = 0; x->port_exists(ii); ++ii) { o << sep << x->port_value(ii); sep = ","; } for (int ii = 0; x->current_port_exists(ii); ++ii) { o << sep << x->current_port_value(ii); sep = ","; } o << ")"; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void LANG_VERILOG::print_paramset(OMSTREAM& o, const MODEL_CARD* x) { assert(x); _mode = mPARAMSET; o << "paramset " << x->short_label() << ' ' << x->dev_type() << ";\\\n"; print_args(o, x); o << "\\\n" "endparmset\n\n"; _mode = mDEFAULT; } /*--------------------------------------------------------------------------*/ void LANG_VERILOG::print_module(OMSTREAM& o, const MODEL_SUBCKT* x) { assert(x); assert(x->subckt()); o << "module " << x->short_label(); print_ports_short(o, x); o << ";\n"; for (CARD_LIST::const_iterator ci = x->subckt()->begin(); ci != x->subckt()->end(); ++ci) { print_item(o, *ci); } o << "endmodule // " << x->short_label() << "\n\n"; } /*--------------------------------------------------------------------------*/ void LANG_VERILOG::print_instance(OMSTREAM& o, const COMPONENT* x) { print_type(o, x); print_args(o, x); print_label(o, x); print_ports_long(o, x); o << ";\n"; } /*--------------------------------------------------------------------------*/ void LANG_VERILOG::print_comment(OMSTREAM& o, const DEV_COMMENT* x) { assert(x); o << x->comment() << '\n'; } /*--------------------------------------------------------------------------*/ void LANG_VERILOG::print_command(OMSTREAM& o, const DEV_DOT* x) { assert(x); o << x->s() << '\n'; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ class CMD_PARAMSET : public CMD { void do_it(CS& cmd, CARD_LIST* Scope) { // already got "paramset" std::string my_name, base_name; cmd >> my_name; unsigned here = cmd.cursor(); cmd >> base_name; //const MODEL_CARD* p = model_dispatcher[base_name]; const CARD* p = lang_verilog.find_proto(base_name, NULL); if (p) { MODEL_CARD* new_card = dynamic_cast(p->clone()); if (exists(new_card)) { assert(!new_card->owner()); lang_verilog.parse_paramset(cmd, new_card); Scope->push_back(new_card); }else{ //BUG// memory leak cmd.warn(bDANGER, here, "paramset: base has incorrect type"); } }else{ cmd.warn(bDANGER, here, "paramset: no match"); } } } p1; DISPATCHER::INSTALL d1(&command_dispatcher, "paramset", &p1); /*--------------------------------------------------------------------------*/ class CMD_MODULE : public CMD { void do_it(CS& cmd, CARD_LIST* Scope) { MODEL_SUBCKT* new_module = new MODEL_SUBCKT; assert(new_module); assert(!new_module->owner()); assert(new_module->subckt()); assert(new_module->subckt()->is_empty()); lang_verilog.parse_module(cmd, new_module); Scope->push_back(new_module); } } p2; DISPATCHER::INSTALL d2(&command_dispatcher, "module|macromodule", &p2); /*--------------------------------------------------------------------------*/ class CMD_VERILOG : public CMD { public: void do_it(CS&, CARD_LIST* Scope) { command("options lang=verilog", Scope); } } p8; DISPATCHER::INSTALL d8(&command_dispatcher, "verilog", &p8); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/m_base.h����������������������������������������������������������������������������������������0000664�0000000�0000000�00000037366�11454012162�0013257�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_base.h,v 26.127 2009/11/09 16:06:11 al Exp $ -*- C++ -*- * Copyright (C) 2003 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ //testing=script,sparse 2009.08.13 #ifndef BASE_H_INCLUDED #define BASE_H_INCLUDED #include "l_lib.h" #include "ap.h" #include "constant.h" /*--------------------------------------------------------------------------*/ class Float; class String; /*--------------------------------------------------------------------------*/ class Base { private: explicit Base(const Base&) {unreachable();} // This private base copy constructor inhibits generation of // copy constructors for its derived classes. protected: explicit Base() {} public: virtual void parse(CS&) = 0; virtual void dump(std::ostream& o)const = 0; virtual ~Base() {} virtual std::string val_string()const {untested(); return "error";} virtual bool to_bool()const {unreachable(); return false;} virtual Base* minus()const {untested(); return NULL;} virtual Base* plus()const {untested(); return NULL;} virtual Base* less(const Base*)const {untested(); return NULL;} virtual Base* less(const Float*)const {untested(); return NULL;} virtual Base* less(const String*)const {untested(); return NULL;} virtual Base* greater(const Base*)const {untested(); return NULL;} virtual Base* greater(const Float*)const {untested(); return NULL;} virtual Base* greater(const String*)const {untested(); return NULL;} virtual Base* leq(const Base*)const {untested(); return NULL;} virtual Base* leq(const Float*)const {untested(); return NULL;} virtual Base* leq(const String*)const {untested(); return NULL;} virtual Base* geq(const Base*)const {untested(); return NULL;} virtual Base* geq(const Float*)const {untested(); return NULL;} virtual Base* geq(const String*)const {untested(); return NULL;} virtual Base* not_equal(const Base*)const {untested(); return NULL;} virtual Base* not_equal(const Float*)const {untested(); return NULL;} virtual Base* not_equal(const String*)const {untested(); return NULL;} virtual Base* equal(const Base*)const {untested(); return NULL;} virtual Base* equal(const Float*)const {untested(); return NULL;} virtual Base* equal(const String*)const {untested(); return NULL;} virtual Base* add(const Base*)const {untested(); return NULL;} virtual Base* add(const Float*)const {untested(); return NULL;} virtual Base* add(const String*)const {untested(); return NULL;} virtual Base* multiply(const Base*)const {untested(); return NULL;} virtual Base* multiply(const Float*)const {untested(); return NULL;} virtual Base* multiply(const String*)const {untested(); return NULL;} virtual Base* subtract(const Base*)const {untested(); return NULL;} virtual Base* subtract(const Float*)const {untested(); return NULL;} virtual Base* subtract(const String*)const {untested(); return NULL;} virtual Base* r_subtract(const Base*)const {untested(); return NULL;} virtual Base* r_subtract(const Float*)const {untested(); return NULL;} virtual Base* r_subtract(const String*)const {untested(); return NULL;} virtual Base* divide(const Base*)const {untested(); return NULL;} virtual Base* divide(const Float*)const {untested(); return NULL;} virtual Base* divide(const String*)const {untested(); return NULL;} virtual Base* r_divide(const Base*)const {untested(); return NULL;} virtual Base* r_divide(const Float*)const {untested(); return NULL;} virtual Base* r_divide(const String*)const {untested(); return NULL;} Base* logic_not()const; Base* logic_or(const Base* X)const; Base* logic_and(const Base* X)const; }; inline CS& operator>>(CS& f, Base& b) {untested();b.parse(f); return f;} inline std::ostream& operator<<(std::ostream& out, const Base& d) {d.dump(out); return out;} /*--------------------------------------------------------------------------*/ template class List_Base :public Base { private: std::list _list; public: virtual void parse(CS& f) = 0; protected: virtual void dump(std::ostream& o)const; virtual ~List_Base(); explicit List_Base() {} explicit List_Base(const List_Base& p) : Base(), _list(p._list) {untested();} public: typedef typename std::list::const_iterator const_iterator; bool is_empty()const {return _list.empty();} size_t size()const {return _list.size();} const_iterator begin()const {return _list.begin();} const_iterator end()const {return _list.end();} const T* front()const {untested();assert(!is_empty()); return _list.front();} const T* back()const {assert(!is_empty()); return _list.back();} T* back() {assert(!is_empty()); return _list.back();} void push_back(T* x) {assert(x); _list.push_back(x);} void pop_back() {assert(!is_empty()); _list.pop_back();} }; /*--------------------------------------------------------------------------*/ template class List :public List_Base { protected: explicit List() {untested();} public: void parse(CS& f); }; /*--------------------------------------------------------------------------*/ #if 0 template class Collection :public List_Base { protected: explicit Collection() {untested();} public: void parse(CS& f); }; #endif /*--------------------------------------------------------------------------*/ class Float :public Base { private: double _data; void dump(std::ostream& o)const {itested(); if (_data==NOT_INPUT) {untested(); o<<"NA"; }else{itested(); o<<_data; } } public: /*implicit*/ Float(const Float& p) :Base(), _data(p._data) {untested();} explicit Float(CS& file) {untested();parse(file);} explicit Float(const std::string& s) {CS cs(CS::_STRING, s); parse(cs);} Float(double x=NOT_INPUT) :_data(x) {} void parse(CS&); double value()const {return _data;} operator double()const {untested();return _data;} std::string val_string()const {return ftos(_data, 0, 15, ftos_EXP);} bool to_bool()const {return (_data != 0);} Base* minus()const {return new Float(-_data);} Base* plus()const {return new Float(_data);} Base* less(const Float* X)const {assert(X); return new Float((_data < X->_data)?1.:0.);} Base* greater(const Float* X)const {assert(X); return new Float((_data > X->_data)?1.:0.);} Base* leq(const Float* X)const {assert(X); return new Float((_data <= X->_data)?1.:0.);} Base* geq(const Float* X)const {assert(X); return new Float((_data >= X->_data)?1.:0.);} Base* not_equal(const Float* X)const {assert(X); return new Float((_data != X->_data)?1.:0.);} Base* equal(const Float* X)const {assert(X); return new Float((_data == X->_data)?1.:0.);} Base* add(const Float* X)const {assert(X); return new Float(_data + X->_data);} Base* multiply(const Float* X)const {assert(X); return new Float(_data * X->_data);} Base* subtract(const Float* X)const {untested();assert(X); return new Float(_data - X->_data);} Base* r_subtract(const Float* X)const {assert(X); return new Float(X->_data - _data);} Base* divide(const Float* X)const {untested();assert(X); return new Float(_data / X->_data);} Base* r_divide(const Float* X)const {assert(X); return new Float(X->_data / _data);} Base* less(const Base* X)const {return ((X) ? (X->greater(this)) : (NULL));} Base* greater(const Base* X)const {return ((X) ? (X->less(this)) : (NULL));} Base* leq(const Base* X)const {return ((X) ? (X->geq(this)) : (NULL));} Base* geq(const Base* X)const {return ((X) ? (X->leq(this)) : (NULL));} Base* not_equal(const Base* X)const {return ((X) ? (X->not_equal(this)) : (NULL));} Base* equal(const Base* X)const {return ((X) ? (X->equal(this)) : (NULL));} Base* add(const Base* X)const {return ((X) ? (X->add(this)) : (NULL));} Base* multiply(const Base* X)const {return ((X) ? (X->multiply(this)) : (NULL));} Base* subtract(const Base* X)const {return ((X) ? (X->r_subtract(this)): (NULL));} Base* r_subtract(const Base* X)const {untested();return ((X) ? (X->subtract(this)) : (NULL));} Base* divide(const Base* X)const {return ((X) ? (X->r_divide(this)) : (NULL));} Base* r_divide(const Base* X)const {untested();return ((X) ? (X->divide(this)) : (NULL));} Base* less(const String*)const {untested();return NULL;} Base* greater(const String*)const {untested();return NULL;} Base* leq(const String*)const {untested();return NULL;} Base* geq(const String*)const {untested();return NULL;} Base* not_equal(const String*)const {untested();return NULL;} Base* equal(const String*)const {untested();return NULL;} Base* add(const String*)const {untested();return NULL;} Base* multiply(const String*)const {untested();return NULL;} Base* subtract(const String*)const {untested();return NULL;} Base* r_subtract(const String*)const {untested();return NULL;} Base* divide(const String*)const {untested();return NULL;} Base* r_divide(const String*)const { return NULL;} bool is_NA()const {untested();return _data == NOT_INPUT;} }; /*--------------------------------------------------------------------------*/ class String :public Base { protected: std::string _data; public: void parse(CS&) {unreachable(); incomplete();} private: void dump(std::ostream& o)const {untested();o << _data;} public: explicit String(CS& file) {untested();parse(file);} explicit String() {} explicit String(const std::string& s) :_data(s) {} operator const std::string&()const {return _data;} std::string val_string()const {untested();return _data;} bool to_bool()const {untested();return (_data != "");} Base* minus()const {untested(); return NULL;} Base* plus()const {untested(); return NULL;} Base* less(const String* X)const {untested();assert(X); return new Float((_data < X->_data)?1.:0.);} Base* greater(const String* X)const {untested();assert(X); return new Float((_data > X->_data)?1.:0.);} Base* leq(const String* X)const {untested();assert(X); return new Float((_data <= X->_data)?1.:0.);} Base* geq(const String* X)const {untested();assert(X); return new Float((_data >= X->_data)?1.:0.);} Base* not_equal(const String* X)const {untested();assert(X); return new Float((_data != X->_data)?1.:0.);} Base* equal(const String* X)const {untested();assert(X); return new Float((_data == X->_data)?1.:0.);} Base* add(const String* X)const {untested();assert(X); return new String(_data + X->_data);} Base* multiply(const String*)const {untested(); return NULL;} Base* subtract(const String*)const {untested(); return NULL;} Base* r_subtract(const String*)const {untested(); return NULL;} Base* divide(const String*)const {untested(); return NULL;} Base* r_divide(const String*)const {untested(); return NULL;} Base* less(const Base* X)const {untested();return ((X) ? (X->greater(this)) : (NULL));} Base* greater(const Base* X)const {untested();return ((X) ? (X->less(this)) : (NULL));} Base* leq(const Base* X)const {untested();return ((X) ? (X->geq(this)) : (NULL));} Base* geq(const Base* X)const {untested();return ((X) ? (X->leq(this)) : (NULL));} Base* not_equal(const Base* X)const {untested();return ((X) ? (X->not_equal(this)) : (NULL));} Base* equal(const Base* X)const {untested();return ((X) ? (X->equal(this)) : (NULL));} Base* add(const Base* X)const {untested();return ((X) ? (X->add(this)) : (NULL));} Base* multiply(const Base* X)const {untested();return ((X) ? (X->multiply(this)) : (NULL));} Base* subtract(const Base* X)const {untested();return ((X) ? (X->r_subtract(this)): (NULL));} Base* r_subtract(const Base* X)const {untested();return ((X) ? (X->subtract(this)) : (NULL));} Base* divide(const Base* X)const { return ((X) ? (X->r_divide(this)) : (NULL));} Base* r_divide(const Base* X)const {untested();return ((X) ? (X->divide(this)) : (NULL));} Base* less(const Float*)const {untested();return NULL;} Base* greater(const Float*)const {untested();return NULL;} Base* leq(const Float*)const {untested();return NULL;} Base* geq(const Float*)const {untested();return NULL;} Base* not_equal(const Float*)const {untested();return NULL;} Base* equal(const Float*)const {untested();return NULL;} Base* add(const Float*)const {untested();return NULL;} Base* multiply(const Float*)const {untested();return NULL;} Base* subtract(const Float*)const {untested();return NULL;} Base* r_subtract(const Float*)const {untested();return NULL;} Base* divide(const Float*)const {untested();return NULL;} Base* r_divide(const Float*)const {untested();return NULL;} }; /*--------------------------------------------------------------------------*/ class Name_String // a string that contains only alnum and _[] :public String { public: void parse(CS&); public: explicit Name_String(CS& file) {parse(file);} explicit Name_String() {untested();} }; /*--------------------------------------------------------------------------*/ class Quoted_String // the first non-blank character is a quote :public String // a repeat of the same character terminates it { public: void parse(CS&); public: explicit Quoted_String(CS& file) {untested();parse(file);} explicit Quoted_String() {untested();} }; /*--------------------------------------------------------------------------*/ class Tail_String // a string that is parsed to the end of a line :public String { public: void parse(CS&); explicit Tail_String(CS& file) {untested();parse(file);} explicit Tail_String() {untested();} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ template List_Base::~List_Base() { for (typename std::list::iterator i = _list.begin(); i != _list.end(); ++i) { assert(*i); delete *i; } } /*--------------------------------------------------------------------------*/ template void List_Base::dump(std::ostream& Out)const {untested(); for (const_iterator i = begin(); i != end(); ++i) {untested(); assert(*i); Out << **i; } } /*--------------------------------------------------------------------------*/ template void List::parse(CS& File) {untested(); //skip_comment(File); unsigned here = File.cursor(); for (;;) {untested(); if (File.match1('[')) {untested(); break; }else{untested(); T* x = new T(File); if (!File.stuck(&here)) {untested(); push(x); }else{untested(); delete x; File.warn(0, "what's this? (List)"); break; } //skip_comment(File); } } } /*--------------------------------------------------------------------------*/ #if 0 template void Collection::parse(CS& File) {untested(); unsigned here = File.cursor(); T* m = new T(File); if (!File.stuck(&here)) {untested(); push(m); }else{untested(); delete m; File.warn(0, "what's this? (Collection)"); } } #endif /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/m_base_in.cc������������������������������������������������������������������������������������0000664�0000000�0000000�00000007021�11454012162�0014064�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_base_in.cc,v 26.125 2009/10/15 20:58:21 al Exp $ -*- C++ -*- * Copyright (C) 2003 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ //testing=script,sparse 2009.08.13 #include "m_base.h" /*--------------------------------------------------------------------------*/ void Float::parse(CS& File) { if (File >> "NA") { _data = NOT_INPUT; }else{ unsigned here = File.cursor(); File >> _data; if (File.stuck(&here)) {untested(); _data = NOT_INPUT; }else{ } } } /*--------------------------------------------------------------------------*/ void Name_String::parse(CS& File) { File.skipbl(); _data = ""; if (File.is_pfloat()) { while (File.is_pfloat()) { _data += File.ctoc(); } if (File.match1("eE")) { _data += File.ctoc(); if (File.match1("+-")) { _data += File.ctoc(); }else{ } while (File.is_digit()) { _data += File.ctoc(); } }else{ } while (File.is_alpha()) { _data += File.ctoc(); } }else{ while (File.is_alpha() || File.is_pfloat() || File.match1("_[]")) { _data += File.ctoc(); } } File.skipbl(); } /*--------------------------------------------------------------------------*/ void Quoted_String::parse(CS& File) {untested(); File.skipbl(); unsigned here = File.cursor(); char quote = File.ctoc(); _data = ""; for (;;) {untested(); if (File.skip1(quote)) {untested(); break; }else if (!File.more()) {untested(); File.warn(0, "end of file in quoted string"); File.warn(0, here, "string begins here"); break; }else{untested(); _data += File.ctoc(); } } File.skipbl(); } /*--------------------------------------------------------------------------*/ void Tail_String::parse(CS& File) {untested(); // c_str static char end_marks[] = "\n"; const char* begin = File.tail().c_str(); File.skipto1(end_marks); const char* end = File.tail().c_str(); assert(end >= begin); while ((--end >= begin) && (isspace(*end))) {untested(); } ++end; assert(end >= begin); _data = std::string(begin, static_cast(end-begin)); } /*--------------------------------------------------------------------------*/ #if 0 void Text_Block::parse(CS& File) {untested(); // c_str const char* begin = File.tail().c_str(); for (;;) {untested(); File.skipto1("\n").skip(); if (File.peek() == '[') {untested(); break; }else{untested(); } } const char* end = File.tail().c_str(); _data = std::string(begin, static_cast(end-begin)); } #endif /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/m_base_math.cc����������������������������������������������������������������������������������0000664�0000000�0000000�00000004030�11454012162�0014404�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_base_math.cc,v 26.114 2009/08/13 16:32:53 al Exp $ -*- C++ -*- * Copyright (C) 2003 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ //testing=script 2009.08.13 #include "m_base.h" /*--------------------------------------------------------------------------*/ std::string new_name() {untested(); static int c = 0; char s[30]; sprintf(s, "EX%04u", ++c); return s; } /*--------------------------------------------------------------------------*/ Base* Base::logic_not()const { if (to_bool()) { return new Float(0.); }else{untested(); return new Float(1.); } } /*--------------------------------------------------------------------------*/ Base* Base::logic_or(const Base* X)const { if ((to_bool()) || (X && X->to_bool())) { return new Float(1.); }else{ return new Float(0.); } } /*--------------------------------------------------------------------------*/ Base* Base::logic_and(const Base* X)const { if (!to_bool() || !X || !X->to_bool()) { return new Float(0.); }else{ return new Float(1.); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/m_cpoly.h���������������������������������������������������������������������������������������0000664�0000000�0000000�00000011622�11454012162�0013456�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_cpoly.h,v 26.83 2008/06/05 04:46:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * structs for fixed order polynomials, in 2 different forms * FPOLY is by function -- f0 = eval of function * f1 = 1st derivative * f2 = 2nd derivative * etc. * f(x) = f0 * f(t) = f0 + f1*(t-x) + f2*(t-x)^2 + ... * CPOLY is by series -- c0 = coeff of x^0 term (constant) * c1 = coeff of x^1 term (1st derivative) * c2 = coeff of x^2 term * etc. * f(x) = c0 + f1*x + f2*x^2 + ... * f(t) = c0 + f1*t + f2*t^2 + ... */ //testing=script,sparse 2006.07.13 #ifndef M_CPOLY_H #define M_CPOLY_H #include "constant.h" /*--------------------------------------------------------------------------*/ struct FPOLY1; struct CPOLY1; /*--------------------------------------------------------------------------*/ struct FPOLY1{ /* first order polynomial */ double x; /* the argument */ double f0; /* the function (c0 + x*f1) */ double f1; /* the first derivative */ explicit FPOLY1() : x(0), f0(0), f1(0) {} FPOLY1(const FPOLY1& p) : x(p.x), f0(p.f0), f1(p.f1) {} explicit FPOLY1(double X,double F0,double F1) : x(X), f0(F0), f1(F1) {} explicit FPOLY1(const CPOLY1& p); ~FPOLY1() {} bool operator==(const FPOLY1& p)const {return (f1==p.f1 && f0==p.f0 && x==p.x);} FPOLY1& operator*=(double s) {f0*=s; f1*=s; return *this;} FPOLY1& operator*=(const FPOLY1& s); FPOLY1& operator+=(double f) {untested(); f0+=f; return *this;} FPOLY1& operator+=(const FPOLY1& s) {untested(); assert(x==s.x); f0+=s.f0; f1+=s.f1; return *this;} FPOLY1 operator-()const {untested(); return FPOLY1(x, -f0, -f1);} double c1()const {assert(f1 == f1); return f1;} double c0()const {assert(f0==f0); assert(f1==f1); assert(x==x); assert(f0!=LINEAR); return (f0 - x * f1);} }; /*--------------------------------------------------------------------------*/ struct CPOLY1{ /* first order polynomial */ double x; /* the argument */ double c0; /* f(x) - x*f'(x), or f0 - x*f1 */ double c1; /* the first derivative */ explicit CPOLY1() : x(0), c0(0), c1(0) {} CPOLY1(const CPOLY1& p) : x(p.x), c0(p.c0), c1(p.c1) {untested();} explicit CPOLY1(double X,double C0,double C1) : x(X), c0(C0), c1(C1) {} explicit CPOLY1(const FPOLY1& p); ~CPOLY1() {} bool operator==(const CPOLY1& p)const {return (c1==p.c1 && c0==p.c0 && x==p.x);} CPOLY1& operator*=(double s) {c0*=s; c1*=s; return *this;} double f1()const {return c1;} double f0()const {return (c0 + x * c1);} }; /*--------------------------------------------------------------------------*/ inline FPOLY1::FPOLY1(const CPOLY1& p) :x(p.x), f0(p.f0()), f1(p.f1()) { assert(p == p); assert(*this == *this); } /*--------------------------------------------------------------------------*/ inline CPOLY1::CPOLY1(const FPOLY1& p) :x(p.x), c0(p.c0()), c1(p.c1()) { assert(p == p); assert(x == x); assert(c1 == c1); assert(c0 == c0); assert(*this == *this); } /*--------------------------------------------------------------------------*/ inline FPOLY1& FPOLY1::operator*=(const FPOLY1& s) { untested(); assert(x == s.x); *this *= s.f0; f1 += f0 * s.f1; return *this; } /*--------------------------------------------------------------------------*/ inline FPOLY1 operator*(FPOLY1 a, const FPOLY1& b) { untested(); a *= b; return a; } /*--------------------------------------------------------------------------*/ inline FPOLY1 operator+(FPOLY1 a, const FPOLY1& b) { untested(); a += b; return a; } /*--------------------------------------------------------------------------*/ inline FPOLY1 operator+(FPOLY1 a, double b) { untested(); a += b; return a; } /*--------------------------------------------------------------------------*/ inline FPOLY1 operator-(double a, const FPOLY1& b) { untested(); return -b + a; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ��������������������������������������������������������������������������������������������������������������src/m_divdiff.h�������������������������������������������������������������������������������������0000664�0000000�0000000�00000004015�11454012162�0013741�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_divdiff.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * divided differences * in: * c = numerator (data points) (lost) * t = denominator (time) * n = size of array * # of divided differences == n-1 * out: * c = "divided differences" (mult by n! to get derivative) */ //testing=script,complete 2006.07.13 /*--------------------------------------------------------------------------*/ #if 0 template inline void divided_differences(T1 c[], int n, const T2 t[]) { untested(); for (int d=1; d=d; --i) { untested(); c[i] = (c[i-1] - c[i]) / (t[i-d] - t[i]); } } } #endif /*--------------------------------------------------------------------------*/ template inline void derivatives(T1 c[], int n, const T2 t[]) { for (int d=1; d=d; --i) { c[i] = d * (c[i-1] - c[i]) / (t[i-d] - t[i]); } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/m_expression.h����������������������������������������������������������������������������������0000664�0000000�0000000�00000012615�11454012162�0014532�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_expression.h,v 26.127 2009/11/09 16:06:11 al Exp $ -*- C++ -*- * Copyright (C) 2003 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ //testing=script 2009.08.12 #include "m_base.h" /*--------------------------------------------------------------------------*/ class Symbol_Table; class CARD_LIST; class Expression; /*--------------------------------------------------------------------------*/ class Token :public Base { private: std::string _name; const Base* _data; std::string _aRgs; public: void parse(CS&) {unreachable();} public: void dump(std::ostream&)const; protected: explicit Token(const std::string Name, const Base* Data, const std::string Args) : _name(Name), _data(Data), _aRgs(Args) {} explicit Token(const Token& P) : Base(), _name(P._name), _data(P._data), _aRgs(P._aRgs) {assert(!_data);} public: virtual ~Token() {if (_data) {delete _data;}else{}} virtual Token* clone()const = 0; const std::string& name()const {return _name;} const Base* data()const {return _data;} const std::string& aRgs()const {return _aRgs;} const std::string full_name()const {return name() + aRgs();} virtual void stack_op(Expression*)const {unreachable();} bool operator==(const Token& P) {untested();return (typeid(*this)==typeid(P)) && (data()==P.data()) && (name()==P.name()) && (aRgs()==P.aRgs());} }; /*--------------------------------------------------------------------------*/ class Token_SYMBOL : public Token { public: explicit Token_SYMBOL(const std::string Name, const std::string Args) : Token(Name, NULL, Args) {} explicit Token_SYMBOL(const Token_SYMBOL& P) : Token(P) {untested();} Token* clone()const {untested();return new Token_SYMBOL(*this);} void stack_op(Expression*)const; }; class Token_BINOP : public Token { public: explicit Token_BINOP(const std::string Name) : Token(Name, NULL, "") {} explicit Token_BINOP(const Token_BINOP& P) : Token(P) {} Token* clone()const {return new Token_BINOP(*this);} Token* op(const Token* t1, const Token* t2)const; void stack_op(Expression*)const; }; class Token_STOP : public Token { public: explicit Token_STOP(const std::string Name) : Token(Name, NULL, "") {} explicit Token_STOP(const Token_STOP& P) : Token(P) {} Token* clone()const {return new Token_STOP(*this);} void stack_op(Expression*)const; }; class Token_PARLIST : public Token { public: explicit Token_PARLIST(const std::string Name) : Token(Name, NULL, "") {} explicit Token_PARLIST(const Token_PARLIST& P) : Token(P) {untested();} Token* clone()const {untested();return new Token_PARLIST(*this);} void stack_op(Expression*)const; }; class Token_UNARY : public Token { public: explicit Token_UNARY(const std::string Name) : Token(Name, NULL, "") {} explicit Token_UNARY(const Token_UNARY& P) : Token(P) {untested();} Token* clone()const {untested();return new Token_UNARY(*this);} Token* op(const Token* t1)const; void stack_op(Expression*)const; }; class Token_CONSTANT : public Token { public: explicit Token_CONSTANT(const std::string Name, const Base* Data, const std::string Args) : Token(Name, Data, Args) {} explicit Token_CONSTANT(const Token_CONSTANT& P) : Token(P) {untested();} Token* clone()const {untested();return new Token_CONSTANT(*this);} void stack_op(Expression*)const; }; /*--------------------------------------------------------------------------*/ class INTERFACE Expression :public List_Base { public: const CARD_LIST* _scope; public: void parse(CS&); void dump(std::ostream&)const; private: // expression-in.cc void arglisttail(CS& File); void arglist(CS& File); void leaf(CS& File); void factor(CS& File); void termtail(CS& File); void term(CS& File); void addexptail(CS& File); void addexp(CS& File); void logicaltail(CS& File); void logical(CS& File); void andtail(CS& File); void andarg(CS& File); void exptail(CS& File); void expression(CS& File); public: explicit Expression() : _scope(NULL) {untested();} explicit Expression(CS& File) : _scope(NULL) {parse(File);} private: // expression-reduce.cc void reduce_copy(const Expression&); public: explicit Expression(const Expression&, const CARD_LIST*); public: // other bool as_bool()const {untested();return (!is_empty() && back()->data());} double eval()const { const Float* f = dynamic_cast(back()->data()); return ((f && size()==1) ? (f->value()) : (NOT_INPUT)); } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������������������������src/m_expression_dump.cc����������������������������������������������������������������������������0000664�0000000�0000000�00000007743�11454012162�0015723�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_expression_dump.cc,v 26.115 2009/08/17 22:49:30 al Exp $ -*- C++ -*- * Copyright (C) 2003 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Reconstructs an infix expression from the RPN. */ //testing=script,sparse 2009.08.12 #include "m_expression.h" /*--------------------------------------------------------------------------*/ void Token::dump(std::ostream& out)const {itested(); out << _name << ' '; } /*--------------------------------------------------------------------------*/ void Expression::dump(std::ostream& out)const { std::vector locals; // a way of faking garbage collection. std::vector stack; // actually use this // The _list is the expression in RPN. // Un-parse it -- back to infix. for (const_iterator i = begin(); i != end(); ++i) { if (dynamic_cast(*i)) { stack.push_back(*i); }else if (dynamic_cast(*i)) { // pop*n push bool been_here = false; std::string tmp(")"); for (;;) { if (stack.empty()) {untested(); throw Exception("bad expression"); }else{ } const Token* t = stack.back(); stack.pop_back(); if (dynamic_cast(t)) { tmp = "(" + tmp; break; }else if (dynamic_cast(t)) { if (been_here) { tmp = ", " + tmp; }else{ been_here = true; } tmp = t->full_name() + tmp; }else{ unreachable(); } } Token* t = new Token_PARLIST(tmp); locals.push_back(t); stack.push_back(t); }else if (dynamic_cast(*i)|| dynamic_cast(*i)) { if (!stack.empty() && (dynamic_cast(stack.back()))) { // has parameters (table or function) // pop op push const Token* t1 = stack.back(); stack.pop_back(); Token* t = new Token_SYMBOL((**i).name(), t1->full_name()); locals.push_back(t); stack.push_back(t); }else{ // has no parameters (scalar) stack.push_back(*i); } }else if (dynamic_cast(*i)) { // pop pop op push assert(!stack.empty()); const Token* t2 = stack.back(); stack.pop_back(); assert(!stack.empty()); const Token* t1 = stack.back(); stack.pop_back(); std::string tmp('(' + t1->full_name() + ' ' + (**i).name() + ' ' + t2->full_name() + ')'); Token* t = new Token_SYMBOL(tmp, ""); locals.push_back(t); stack.push_back(t); }else if (dynamic_cast(*i)) { // pop op push assert(!stack.empty()); const Token* t1 = stack.back(); stack.pop_back(); std::string tmp('(' + (**i).name() + ' ' + t1->full_name() + ')'); Token* t = new Token_SYMBOL(tmp, ""); locals.push_back(t); stack.push_back(t); }else{ unreachable(); } } if (stack.empty()) {untested(); out << "empty"; }else{ out << stack.back()->full_name(); assert(stack.size() == 1); } while (!locals.empty()) { delete locals.back(); locals.pop_back(); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������src/m_expression_in.cc������������������������������������������������������������������������������0000664�0000000�0000000�00000013677�11454012162�0015367�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_expression_in.cc,v 26.115 2009/08/17 22:49:30 al Exp $ -*- C++ -*- * Copyright (C) 2003 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Classic recursive descent parser. * Builds a RPN representation in _list. * Numbers stay as strings. * * BNF: * arglisttail : "," expression arglisttail * | nothing * arglist : "(" expression arglisttail ")"; * | "(" ")" * | nothing * leaf : name arglist * factor : unary "(" expression ")" * | unary leaf * termtail : "*" factor termtail * | "/" factor termtail * | nothing * term : factor termtail * addexptail : "+" term addexptail * | "-" term addexptail * | nothing * addexp : term addexptail * logicaltail : "<" addexp logicaltail * | ">" addexp logicaltail * | "<=" addexp logicaltail * | ">=" addexp logicaltail * | "==" addexp logicaltail * | "!=" addexp logicaltail * | nothing * logical : addexp logicaltail * andtail : "&&" logical andtail * | nothing * andarg : logical andtail * exptail : "||" andarg exptail * | nothing * expression : andarg exptail */ //testing=script 2009.08.12 #include "m_expression.h" /*--------------------------------------------------------------------------*/ void Expression::arglisttail(CS& File) { if (File.skip1b(",")) { expression(File); arglisttail(File); }else{ } } /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ void Expression::arglist(CS& File) { if (File.skip1b("(")) { push_back(new Token_STOP("(")); if (!File.skip1b(")")) { expression(File); arglisttail(File); if (!File.skip1b(")")) {itested(); throw Exception_CS("unbalanced parentheses (arglist)", File); }else{ } }else{ } push_back(new Token_PARLIST(")")); }else{ } } /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ void Expression::leaf(CS& File) { #if 0 if (File.peek() == '"') {untested(); Quoted_String name(File); push_back(new Token_SYMBOL(name, "")); // do not put constants in symbol table } // else #endif unsigned here = File.cursor(); Name_String name(File); if (!File.stuck(&here)) { arglist(File); push_back(new Token_SYMBOL(name, "")); }else{itested(); throw Exception_CS("what's this?", File); } } /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ void Expression::factor(CS& File) { Token* t = 0; if (File >> "-|+|!") { std::string name(File.last_match()); t = new Token_UNARY(name); }else{ } if (File.skip1b("(")) { expression(File); if (!File.skip1b(")")) {untested(); throw Exception_CS("unbalanced parentheses (factor)", File); }else{ } }else{ leaf(File); } if (t) { push_back(t); }else{ } } /*--------------------------------------------------------------------------*/ void Expression::termtail(CS& File) { if (File >> "*|/") { std::string name(File.last_match()); factor(File); push_back(new Token_BINOP(name)); termtail(File); }else{ } } /*--------------------------------------------------------------------------*/ void Expression::term(CS& File) { factor(File); termtail(File); } /*--------------------------------------------------------------------------*/ void Expression::addexptail(CS& File) { if (File >> "+|-") { std::string name(File.last_match()); term(File); push_back(new Token_BINOP(name)); addexptail(File); }else{ } } /*--------------------------------------------------------------------------*/ void Expression::addexp(CS& File) { term(File); addexptail(File); } /*--------------------------------------------------------------------------*/ void Expression::logicaltail(CS& File) { if (File >> "<=|<|>=|>|==|!=") { std::string name(File.last_match()); addexp(File); push_back(new Token_BINOP(name)); logicaltail(File); }else{ } } /*--------------------------------------------------------------------------*/ void Expression::logical(CS& File) { addexp(File); logicaltail(File); } /*--------------------------------------------------------------------------*/ void Expression::andtail(CS& File) { if (File >> "&&") { std::string name(File.last_match()); logical(File); push_back(new Token_BINOP(name)); andtail(File); }else{ } } /*--------------------------------------------------------------------------*/ void Expression::andarg(CS& File) { logical(File); andtail(File); } /*--------------------------------------------------------------------------*/ void Expression::exptail(CS& File) { if (File >> "\\|\\|") { // "||" std::string name(File.last_match()); andarg(File); push_back(new Token_BINOP(name)); exptail(File); }else{ } } /*--------------------------------------------------------------------------*/ void Expression::expression(CS& File) { andarg(File); exptail(File); } /*--------------------------------------------------------------------------*/ void Expression::parse(CS& File) { expression(File); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������src/m_expression_reduce.cc��������������������������������������������������������������������������0000664�0000000�0000000�00000021575�11454012162�0016224�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_expression_reduce.cc,v 26.127 2009/11/09 16:06:11 al Exp $ -*- C++ -*- * Copyright (C) 2003 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Reconstructs an infix expression from the RPN. * Incomplete: * Expressions in arg-lists print as ####false#### * Not sure what should happen when expression is empty */ //testing=script,sparse 2009.08.12 #include "u_function.h" #include "u_parameter.h" /*--------------------------------------------------------------------------*/ Token* Token_BINOP::op(const Token* T1, const Token* T2)const { assert(T1); assert(T2); assert(dynamic_cast(T1)); assert(dynamic_cast(T2)); assert(T1->data()); assert(T2->data()); // not "or" operator, both ops exist -- do it Base* b = 0; if (name() == "*") { b = (T1->data())->multiply(T2->data()); }else if (name() == "+") { b = (T1->data())->add(T2->data()); }else if (name() == "-") { b = (T1->data())->subtract(T2->data()); }else if (name() == "/") { b = (T1->data())->divide(T2->data()); }else if (name() == "==") { b = (T1->data())->equal(T2->data()); }else if (name() == "!=") { b = (T1->data())->not_equal(T2->data()); }else if (name() == "<") { b = (T1->data())->less(T2->data()); }else if (name() == ">") { b = (T1->data())->greater(T2->data()); }else if (name() == "<=") { b = (T1->data())->leq(T2->data()); }else if (name() == ">=") { b = (T1->data())->geq(T2->data()); }else if (name() == "||") { b = (T1->data())->logic_or(T2->data()); }else if (name() == "&&") { b = (T1->data())->logic_and(T2->data()); }else{ // op (name()) not one of those listed unreachable(); return NULL; } if (b) { if (T1->aRgs() == "") { }else{untested(); } if (T2->aRgs() == "") { }else{untested(); } return new Token_CONSTANT(b->val_string(), b, (T1->aRgs()+T2->aRgs())); }else{ // can get here if either T1 or T2 has no data return new Token_CONSTANT("false", NULL, ""); } } /*--------------------------------------------------------------------------*/ Token* Token_UNARY::op(const Token* T1)const { assert(T1); assert(dynamic_cast(T1)); assert(T1->data()); const Base* b = 0; if (name() == "-") { b = (T1->data())->minus(); }else if (name() == "+") { b = (T1->data())->plus(); }else if (name() == "!") { b = (T1->data())->logic_not(); }else{ // op (name()) not one of those listed unreachable(); return NULL; } if (b) { if (T1->aRgs() == "") { }else{untested(); } return new Token_CONSTANT(b->val_string(), b, (T1->aRgs())); }else{untested(); // can get here if T1 has no data return new Token_CONSTANT("false", NULL, ""); } } /*--------------------------------------------------------------------------*/ void Token_SYMBOL::stack_op(Expression* E)const { assert(E); // replace single token with its value if (!E->is_empty() && dynamic_cast(E->back())) { // has parameters (table or function) if (FUNCTION* f = function_dispatcher[name()]) { const Token* T1 = E->back(); // arglist E->pop_back(); CS cmd(CS::_STRING, T1->name()); std::string value = f->eval(cmd, E->_scope); const Float* v = new Float(value); E->push_back(new Token_CONSTANT(value, v, "")); delete T1; }else{ throw Exception_No_Match(name()); //BUG// memory leak unreachable(); E->push_back(clone()); } }else{ // has no parameters (scalar) if (strchr("0123456789.", name()[0])) { // a number Float* n = new Float(name()); E->push_back(new Token_CONSTANT(name(), n, "")); }else{ // a name PARAMETER p = (*(E->_scope->params()))[name()]; if (p.has_hard_value()) { // can find value - push value double v = p.e_val(NOT_INPUT, E->_scope); Float* n = new Float(v); E->push_back(new Token_CONSTANT(n->val_string(), n, "")); }else{ // no value - push name (and accept incomplete solution later) String* s = new String(name()); E->push_back(new Token_CONSTANT(name(), s, "")); } } } } /*--------------------------------------------------------------------------*/ void Token_BINOP::stack_op(Expression* E)const { assert(E); // replace 2 tokens (binop) with 1 (result) Token* t1 = E->back(); E->pop_back(); Token* t2 = E->back(); E->pop_back(); if (dynamic_cast(t1)) { if (dynamic_cast(t2)) { // have # # + .. becomes result (the usual) Token* t = op(t2, t1); assert(t); if (t->data()) { // success E->push_back(t); delete t2; delete t1; }else{ // fail - one arg is unknown, push back args if (strchr("+*", name()[0]) && !dynamic_cast(t1->data())) {untested(); // change order to enable later optimization E->push_back(t1); E->push_back(t2); }else{ E->push_back(t2); E->push_back(t1); } E->push_back(clone()); //op delete t; } }else if (((*t2) == (*this)) && strchr("+*", name()[0]) && dynamic_cast(E->back())) {untested(); // have # + # + .. becomes result + (previous unknown, try to optimize) Token* t3 = E->back(); E->pop_back(); Token* t = op(t3, t1); assert(t); if (t->data()) {untested(); // success E->push_back(t); E->push_back(t2); delete t3; delete t1; }else{untested(); // fail - push all E->push_back(t3); E->push_back(t2); E->push_back(t1); E->push_back(clone()); delete t; } }else{untested(); // # - # - or something like that E->push_back(t2); E->push_back(t1); E->push_back(clone()); } }else{untested(); // # - # - or something like that E->push_back(t2); E->push_back(t1); E->push_back(clone()); } } /*--------------------------------------------------------------------------*/ void Token_STOP::stack_op(Expression* E)const { assert(E); E->push_back(clone()); } /*--------------------------------------------------------------------------*/ void Token_PARLIST::stack_op(Expression* E)const { assert(E); // replace multiple tokens of a PARLIST with a single token bool been_here = false; std::string tmp;//(")"); for (;;) { const Token* t = E->back(); E->pop_back(); if (dynamic_cast(t)) { // tmp = "(" + tmp; break; }else{ if (been_here) { tmp = ", " + tmp; }else{ been_here = true; } tmp = t->name() + tmp; } delete t; } E->push_back(new Token_PARLIST(tmp)); } /*--------------------------------------------------------------------------*/ void Token_UNARY::stack_op(Expression* E)const { assert(E); // replace 1 token with 1 (result) Token* t1 = E->back(); E->pop_back(); if (dynamic_cast(t1)) { Token* t = op(t1); assert(t); if (t->data()) { E->push_back(t); delete t1; }else{untested(); E->push_back(t1); E->push_back(clone()); delete t; } }else{untested(); E->push_back(t1); E->push_back(clone()); } } /*--------------------------------------------------------------------------*/ void Token_CONSTANT::stack_op(Expression* E)const { unreachable(); assert(E); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void Expression::reduce_copy(const Expression& Proto) { // The Proto._list is the expression in RPN. // Attempt to build a reduced _list here, hopefully with only one item. for (const_iterator i = Proto.begin(); i != Proto.end(); ++i) { (**i).stack_op(this); } if (is_empty()) {untested(); assert(Proto.is_empty()); }else{ } } /*--------------------------------------------------------------------------*/ Expression::Expression(const Expression& Proto, const CARD_LIST* Scope) :_scope(Scope) { reduce_copy(Proto); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������������������������������������������������������������������������src/m_fft.cc����������������������������������������������������������������������������������������0000664�0000000�0000000�00000004106�11454012162�0013244�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_fft.cc,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * fast fourier transform */ //testing=script 2006.07.13 #include "constant.h" #include "declare.h" /* self */ /*--------------------------------------------------------------------------*/ void fft(COMPLEX* x, int n, int inv) { int s = (inv) ? 1 : -1; int nxp, nxp2; for (nxp=n; (nxp2=nxp/2) > 0; nxp=nxp2) { double wpwr = M_TWO_PI / nxp; for (int m = 0; m < nxp2; ++m) { double argg = m * wpwr; COMPLEX w(cos(argg), s*sin(argg)); for (int jj1 = m; jj1+nxp-m <= n; jj1 += nxp) { int jj2 = jj1 + nxp2; COMPLEX t = x[jj1] - x[jj2]; x[jj1] += x[jj2]; x[jj2] = t * w; } } } /* unscramble */ { int i, j; for (/*k =*/ i = j = 0; i < n-1; ++i) { if (i < j) { swap(x[i],x[j]); } int k; for (k = n/2; k <= j; k /= 2) { j -= k; } j += k; } } /* fix level */ if (!inv) { for (int i = 0; i < n; ++i) { x[i] /= n; } }else{ untested(); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/m_interp.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000006331�11454012162�0013632�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_interp.h,v 26.83 2008/06/05 04:46:59 al Exp $ -*- C++ -*- * interpolation on a sorted array * * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script,sparse 2006.07.13 #ifndef M_INTERP_H #define M_INTERP_H #include "m_cpoly.h" /*--------------------------------------------------------------------------*/ /* interpolate: linear interpolation on a table. * Keys must be sorted in increasing order. */ template FPOLY1 interpolate(Iterator begin, Iterator end, double x, double below, double above) { double f1 = NOT_VALID; double f0 = NOT_VALID; if (begin == end) { untested(); throw Exception("interpolate table is empty"); } --end; if (begin == end) { // only 1 entry -- constant untested(); f1 = (x < (*begin).first) ? ((below != NOT_INPUT) ? below : 0.) : ((above != NOT_INPUT) ? above : 0.); f0 = (*begin).second + (x - (*begin).first) * f1; }else{ ++begin; // x is the search key // xx is the search key converted to a "pair" as required by upper_bound // upper might point to a match for the key, exact match // if not, it points just above it, no exact match // lower points just below where a match would go // so the real match is between upper and lower DPAIR xx(x,BIGBIG); Iterator upper = upper_bound(begin, end, xx); Iterator lower = upper-1; // set f1 (derivative) if ((upper == end) && (x > (*upper).first) && (above != NOT_INPUT)) { // x is out of bounds, above lower = upper; if (above != 0.) { untested(); } f1 = above; }else if ((upper == begin) && (x < (*lower).first) && (below!=NOT_INPUT)) { // x is out of bounds, below untested(); if (below != 0.) { untested(); }else{ untested(); } f1 = below; }else if ((*upper).first <= (*lower).first) {untested(); throw Exception("interpolate table is not sorted or has duplicate keys"); f1 = 0.; }else{ // ordinary interpolation assert((*upper).first != (*lower).first); f1 = ((*upper).second-(*lower).second) / ((*upper).first-(*lower).first); } f0 = (*lower).second + (x - (*lower).first) * f1; } assert(f1 != NOT_VALID); assert(f0 != NOT_VALID); return FPOLY1(x, f0, f1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/m_matrix.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000052014�11454012162�0013634�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_matrix.h,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Sparse matrix package * Bump and spike - bordered block diagonal pattern * ------------------------------------------------- * To use it (simple method) ..... * 1. Declare it ... * BSMATRIX a; * 2. Then tell it what slots to allocate, in a loop ... * for (all pairs i,j that might exist) * a.iwant(i,j); * 3. Then do the actual allocation ... * a.allocate(); * 4. If you want, you can add an offset to the diagonal ... * a.dezero(gmin); * 5. You probably should set a minimum pivot value ... * a.setminpivot(gmin); * 6. Fill in the matrix ... * for (all pairs i,j you want to fill in) * a.m(i,j) += data; * 7. Then do the LU decomposition ... * a.lu_decomp(); * 8. Then get the solution by applying the right side vector (v) * and doing the fwd and back substitution. * a.fbsub(v); * The solution is now in v. * ------------------------------------------------- * To reuse it ..... * Get rid of the old data ... * a.zero(). * Restore the offset, if you want ... * a.dezero(gmin); * Then fill and solve as before. (steps 6-8) * ------------------------------------------------- * In the above case, LU replaced the matrix and the solution replaced * the right side, losing the data. * To keep the matrix, and keep the right side ... * 1. Declare two matrices ... * BSMATRIX a; * BSMATRIX lu; * 2. as before * 2a. Say the lu has the same structure as a. * lu.clone(a); * 3-5. Allocate both. * 6. Fill in "a" only. * 7. Do the LU decomposition, keeping a, with result in lu ... * lu.lu_decomp(a, false); * 8. Do the f&B sub, keeping b (the right side), with result in x ... * lu.fbsub(x, b); * ------------------------------------------------- * To make a change to the matrix and re-solve ... * Apply the change to a ... * for (all changes you want to make) * a.m(i,j) += delta; a.set_changed(i).set_changed(j) * Then solve again .. step 7 above for a full solution, * or for an update ... * lu.lu_decomp(a, true); * Then do the same step 8 as above. * ------------------------------------------------- * some other functions that might be useful .... * reinit(newsize) -- change the size (and lose the contents and structure) * size()const -- return the size (# of rows & cols) * density()const -- return the matrix density, as a number between 0 and 1 * sparsity()const -- 1-density * ------------------------------------------------- * individual element access ... * 5 access functions are provided. * All return lvalues (references to the actual entry). * All take 2 args, row and column. They differ in speed and generality. * Since they are used in equations, they all have 1 letter names. * s(r,c) -- "safe" -- most general case, with bounds checking * if completely out of bounds, returns trash * if in the matrix but out of band, returns a reference to zero * Changing it will corrupt the matrix. * All others have no bounds checking. * m(r,c) -- "matrix" -- known to be within the allocated band * u(r,c) -- "upper" -- known to be in the upper triangle. (c>=r) * l(r,c) -- "lower" -- known to be in the lower triangle. (r>=c) * d(r,c) -- "diagonal" -- known to be on the diagonal. (r==c) * Using s() will always work, but will be slower than the other methods. * You should use the most restricted function that you know is correct. * ------------------------------------------------- * Other notes ... * The numbering starts at 1 (Fortran style). * When using "s" access, it is ok to load row and column 0, then ignore it. * This may simplify load functions, at the expense of run speed. * "s" will let you change the value of zero, * but you will find out about it later. */ //testing=script 2008.09.19 #ifndef M_MATRIX_H #define M_MATRIX_H /*--------------------------------------------------------------------------*/ #include "l_stlextra.h" /*--------------------------------------------------------------------------*/ template class BSMATRIX { private: mutable bool* _changed;// flag: this node changed value int* _lownode; // lowest node connecting to this one T* _space; // ptr to actual memory space used T** _rowptr; // ptrs to col 0 of every row T** _colptr; // ptrs to row 0 of every col T** _diaptr; // ptrs to diagonal int _nzcount; // count of non-zero elements int _size; // # of rows and columns T _zero; // always 0 but not const T _trash; // depository for row and col 0, write only T _min_pivot; // minimum pivot value private: explicit BSMATRIX(const BSMATRIX&) {incomplete();unreachable();} void uninit(); void init(int s=0); T& subtract_dot_product(int r, int c, int d); T& subtract_dot_product(int r, int c, int d, const T& in); int lownode(int i)const {return _lownode[i];} bool is_changed(int n)const {return _changed[n];} void set_changed(int n, bool x = true)const {_changed[n] = x;} public: explicit BSMATRIX(int ss=0); ~BSMATRIX() {uninit();} void reinit(int ss=0) {uninit(); init(ss);} //void clone(const BSMATRIX&); void iwant(int, int); void unallocate(); void allocate(); void reallocate() {unallocate(); allocate();} void set_min_pivot(double x) {_min_pivot = x;} void zero(); void dezero(T& o); int size()const {return _size;} double density(); T d(int r, int )const {return *(_diaptr[r]);} private: T u(int r, int c)const {return _colptr[c][r];} T l(int r, int c)const {return _rowptr[r][-c];} T& d(int r, int c); T& u(int r, int c); T& l(int r, int c); T& m(int r, int c); //T& s(int r, int c); public: void load_diagonal_point(int i, T value); void load_point(int i, int j, T value); void load_couple(int i, int j, T value); void load_symmetric(int i, int j, T value); void load_asymmetric(int r1, int r2, int c1, int c2, T value); void lu_decomp(const BSMATRIX&, bool do_partial); void lu_decomp(); void fbsub(T* v) const; void fbsub(T* x, const T* b, T* c = NULL) const; }; /*--------------------------------------------------------------------------*/ // private implementations /*--------------------------------------------------------------------------*/ template void BSMATRIX::uninit() { unallocate(); delete [] _lownode; _lownode = NULL; delete [] _changed; _changed = NULL; } /*--------------------------------------------------------------------------*/ template void BSMATRIX::init(int ss) { assert(!_lownode); assert(!_colptr); assert(!_rowptr); assert(!_diaptr); assert(!_space); assert(_zero == 0.); _min_pivot = _trash = 0.; _nzcount = 0; _size = ss; _lownode = new int[size()+1]; assert(_lownode); for (int ii = 0; ii <= size(); ++ii) { _lownode[ii] = ii; } _changed = new bool[size()+1]; assert(_changed); for (int ii = 0; ii <= size(); ++ii) { set_changed(ii, false); } } /*--------------------------------------------------------------------------*/ template T& BSMATRIX::subtract_dot_product(int rr, int cc, int dd) { assert(_lownode); int kk = std::max(_lownode[rr], _lownode[cc]); int len = dd - kk; T& dot = m(rr, cc); if (len > 0) { T* row = &(l(rr,kk)); T* col = &(u(kk,cc)); /* for (ii = kk; ii < dd; ++ii) */ for (int ii = 0; ii < len; ++ii) { dot -= row[-ii] * col[ii]; } }else{ } return dot; } /*--------------------------------------------------------------------------*/ template T& BSMATRIX::subtract_dot_product(int rr, int cc, int dd, const T& in) { assert(_lownode); int kk = std::max(_lownode[rr], _lownode[cc]); int len = dd - kk; T& dot = m(rr, cc); dot = in; if (len > 0) { T* row = &(l(rr,kk)); T* col = &(u(kk,cc)); /* for (ii = kk; ii < dd; ++ii) */ for (int ii = 0; ii < len; ++ii) { dot -= row[-ii] * col[ii]; } }else{ } return dot; } /*--------------------------------------------------------------------------*/ // public implementations /*--------------------------------------------------------------------------*/ template BSMATRIX::BSMATRIX(int ss) :_changed(NULL), _lownode(NULL), _space(NULL), _rowptr(NULL), _colptr(NULL), _diaptr(NULL), _nzcount(0), _size(ss), _zero(0.), _trash(0.), _min_pivot(0.) { init(ss); } /*--------------------------------------------------------------------------*/ #if 0 /* clone: copy to self the structure of another BSMATRIX * this does not copy the values stored in the matrix */ template void BSMATRIX::clone(const BSMATRIX & aa) {untested(); reinit(aa.size()); for (int ii = 0; ii <= size(); ++ii) {untested(); _lownode[ii] = aa.lownode(ii); } } #endif /*--------------------------------------------------------------------------*/ /* iwant: indicate that "iwant" to allocate this spot in the matrix */ template void BSMATRIX::iwant(int node1, int node2) { assert(_lownode); assert(node1 <= size()); assert(node2 <= size()); if (node1 <= 0 || node2 <= 0) { // node 0 is ground, and doesn't count as a connection // negative is invalid, not used but still may be in a node list }else if (node1 < _lownode[node2]) { _lownode[node2]=node1; }else if (node2 < _lownode[node1]) { _lownode[node1]=node2; }else{ } } /*--------------------------------------------------------------------------*/ template void BSMATRIX::unallocate() { assert (_zero == 0.); delete [] _rowptr; delete [] _colptr; delete [] _diaptr; delete [] _space; _rowptr = _colptr = _diaptr = NULL; _space = NULL; } /*--------------------------------------------------------------------------*/ /* allocate: really get the space to work */ template void BSMATRIX::allocate() { assert(_lownode); assert(!_colptr); assert(!_rowptr); assert(!_diaptr); assert(!_space); _nzcount = 0; for (int ii = 0; ii <= size(); ++ii) { _nzcount += 2 * (ii - _lownode[ii]) + 1; } _colptr = new T*[size()+1]; _rowptr = new T*[size()+1]; _diaptr = new T*[size()+1]; _space = new T[_nzcount]; assert(_colptr); assert(_rowptr); assert(_diaptr); zero(); { T* point = _space; for (int ii = 0; ii <= size(); ++ii) { _colptr[ii] = point - _lownode[ii]; _rowptr[ii] = _colptr[ii] + 2*ii; _diaptr[ii] = _colptr[ii] + ii; point += 2 * (ii - _lownode[ii]) + 1; } } } /*--------------------------------------------------------------------------*/ /* zero: wipe the whole array */ template void BSMATRIX::zero() { assert(_space); assert(_zero == 0.); _trash = 0.; std::fill_n(_space, _nzcount, 0.); } /*--------------------------------------------------------------------------*/ /* dezero: make sure(?) the diagonal is non-zero */ template void BSMATRIX::dezero(T& offset) { for (int ii = 1; ii <= size(); ++ii) { d(ii,ii) += offset; } } /*--------------------------------------------------------------------------*/ template double BSMATRIX::density() { if (size() > 0) { assert(_lownode); _nzcount = 0; for (int ii = 0; ii <= size(); ++ii) { _nzcount += 2 * (ii - _lownode[ii]) + 1; } return static_cast(_nzcount-1)/(static_cast(size())*size()); }else{ return 0; } } /*--------------------------------------------------------------------------*/ /* d: fast matrix entry access, lvalue * It is known that the entry is valid and on the diagonal */ template T& BSMATRIX::d(int r, int c) { assert(_diaptr); assert(r == c); assert(0 <= r); assert(r <= _size); return *(_diaptr[r]); } /*--------------------------------------------------------------------------*/ /* u: fast matrix entry access * It is known that the entry is valid and in the upper triangle */ template T& BSMATRIX::u(int r, int c) { assert(_colptr); assert(_lownode); assert(0 < r); assert(r <= c); assert(c <= _size); assert(1 <= _lownode[c]); assert(_lownode[c] <= r); return _colptr[c][r]; } /*--------------------------------------------------------------------------*/ /* l: fast matrix entry access * It is known that the entry is valid and in the lower triangle */ template T& BSMATRIX::l(int r, int c) { assert(_rowptr); assert(_lownode); assert(0 < c); assert(c <= r); assert(r <= _size); assert(1 <= _lownode[r]); assert(_lownode[r] <= c); return _rowptr[r][-c]; } /*--------------------------------------------------------------------------*/ /* m: semi-fast matrix entry access * It is known that the entry refers to a valid location * but it is not known whether lower, upper, or diagonal */ template T& BSMATRIX::m(int r, int c) { return (c>=r) ? u(r,c) : l(r,c); } /*--------------------------------------------------------------------------*/ /* s: general matrix entry access. * It is known that the location is strictly in bounds, * but it is not known whether the location actually exists. * If access is attempted to a non-allocated location, * it returns a reference to a shared zero variable. * Writing to this zero is not prohibited, * but will corrupt the matrix in a known and testable way. * If access is attempted to row 0 or column 0, * it returns a reference to a shared trash variable. * Writing to trash is allowed and encouraged, * but reading it gives a number not useful for anything. */ #if 0 template T& BSMATRIX::s(int row, int col) {untested(); assert(_lownode); assert(0 <= col); assert(col <= size()); assert(0 <= row); assert(row <= size()); assert(_zero == 0.); if (col == row) {untested(); return d(row,col); }else if (col > row) {untested(); /* above the diagonal */ if (row == 0) {untested(); return _trash; }else if (row < _lownode[col]) {untested(); return _zero; }else{untested(); return u(row,col); } }else{untested(); /* below the diagonal */ assert(col < row); if (col == 0) {untested(); return _trash; }else if (col < _lownode[row]) {untested(); return _zero; }else{untested(); return l(row,col); } } unreachable(); } #endif /*--------------------------------------------------------------------------*/ template void BSMATRIX::load_point(int i, int j, T value) { if (i > 0 && j > 0) { set_changed(j); set_changed(i); m(i,j) += value; }else{ } } /*--------------------------------------------------------------------------*/ // load_point(i, i, value); template void BSMATRIX::load_diagonal_point(int i, T value) { if (i > 0) { set_changed(i); d(i,i) += value; }else{untested(); } } /*--------------------------------------------------------------------------*/ // load_point(i, j, -value); // load_point(j, i, -value); template void BSMATRIX::load_couple(int i, int j, T value) { if (j > 0) { set_changed(j); if (i > 0) { set_changed(i); m(i,j) -= value; m(j,i) -= value; }else{ } }else{untested(); } } /*--------------------------------------------------------------------------*/ // load_point(i, i, value); or load_diagonal_point(i, value); // load_point(j, j, value); or load_diagonal_point(j, value); // load_point(i, j, -value); // load_point(j, i, -value); template void BSMATRIX::load_symmetric(int i, int j, T value) { if (j > 0) { set_changed(j); d(j,j) += value; if (i > 0) { set_changed(i); d(i,i) += value; m(i,j) -= value; m(j,i) -= value; }else{ } }else if (i > 0) { set_changed(i); d(i,i) += value; }else{ } } /*--------------------------------------------------------------------------*/ // load_point(r1, c1, value); // load_point(r2, c2, value); // load_point(r1, c2, -value); // load_point(r2, c1, -value); template void BSMATRIX::load_asymmetric(int r1,int r2,int c1,int c2,T value) { set_changed(c1); set_changed(c2); if (r1 > 0) { set_changed(r1); if (c1 > 0) { m(r1,c1) += value; }else{ } if (c2 > 0) { m(r1,c2) -= value; }else{ } }else{ } if (r2 > 0) { set_changed(r2); if (c1 > 0) { m(r2,c1) -= value; }else{ } if (c2 > 0) { m(r2,c2) += value; }else{ } }else{ } } /*--------------------------------------------------------------------------*/ template void BSMATRIX::lu_decomp(const BSMATRIX& aa, bool do_partial) { int prop = 0; /* change propagation indicator */ assert(_lownode); assert(aa._lownode); assert(aa.size() == size()); for (int mm = 1; mm <= size(); ++mm) { assert(aa.lownode(mm) == _lownode[mm]); int bn = _lownode[mm]; if (!do_partial || aa.is_changed(mm) || bn <= prop) { aa.set_changed(mm, false); prop = mm; if (bn < mm) { prop = mm; u(bn,mm) = aa.u(bn,mm) / d(bn,bn); for (int ii = bn+1; ii void BSMATRIX::lu_decomp() { assert(_lownode); for (int mm = 1; mm <= size(); ++mm) { int bn = _lownode[mm]; if (bn < mm) { u(bn,mm) /= d(bn,bn); for (int ii =bn+1; ii void BSMATRIX::fbsub(T* v) const { assert(_lownode); assert(v); for (int ii = 1; ii <= size(); ++ii) { /* forward substitution */ for (int jj = _lownode[ii]; jj < ii; ++jj) { v[ii] -= l(ii,jj) * v[jj]; } v[ii] /= d(ii,ii); } for (int jj = size(); jj > 1; --jj) { /* back substitution */ for (int ii = _lownode[jj]; ii < jj; ++ii) { v[ii] -= u(ii,jj) * v[jj]; } } } /*--------------------------------------------------------------------------*/ /* fbsub: forward and back sub, separate storage * b = right side vector * c = intermediate vector after fwd sub * x = solution vector */ template void BSMATRIX::fbsub(T* x, const T* b, T* c) const { assert(_lownode); assert(x); assert(b); assert(c); { int ii = 1; for ( ; ii <= size(); ++ii) { if (b[ii] != 0.) { break; }else{ } c[ii] = 0.; } int first_nz = ii; for ( ; ii <= size(); ++ii) { /* forward substitution */ int low_node = std::max(_lownode[ii], first_nz); c[ii] = b[ii]; for (int jj = low_node; jj < ii; ++jj) { c[ii] -= l(ii,jj) * c[jj]; } c[ii] /= d(ii,ii); } } notstd::copy_n(c, size()+1, x); for (int jj = size(); jj > 1; --jj) { /* back substitution */ for (int ii = _lownode[jj]; ii < jj; ++ii) { x[ii] -= u(ii,jj) * x[jj]; } } x[0] = 0.; //BUG// some things don't work unless there is a zero here. } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/m_phase.h���������������������������������������������������������������������������������������0000664�0000000�0000000�00000003502�11454012162�0013426�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_phase.h,v 26.118 2009/08/22 21:08:57 al Exp $ -*- C++ -*- * Copyright (C) 2008 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ //testing=script 2008.06.06 #ifndef M_PHASE_H #define M_PHASE_H #include "constant.h" #include "u_opt.h" /*--------------------------------------------------------------------------*/ /* phase: extract phase (degrees) from COMPLEX number * rotates 90 degrees! (ref to sine instead of cosine) */ inline double phase(COMPLEX x) { double rv = NOT_VALID; switch (OPT::phase) { case pDEGREES: rv = arg(x)*RTOD; break; case pP_DEGREES:untested(); rv = arg(x)*RTOD; if (rv < 0) {untested(); rv += 360; }else{untested(); } break; case pN_DEGREES:itested(); rv = arg(x)*RTOD; if (rv > 0) {itested(); rv -= 360; }else{itested(); } break; case pRADIANS: rv = arg(x); break; }; return rv; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/m_spline.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000020730�11454012162�0013760�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_spline.cc,v 26.83 2008/06/05 04:46:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * piecewise polynomial interpolation */ //testing=script 2006.04.18 #include "m_cpoly.h" #include "l_denoise.h" #include "m_spline.h" /*--------------------------------------------------------------------------*/ SPLINE::SPLINE(const std::vector& table, double d0, double dn, int order) :_n(static_cast(table.size())-1), _x( new double[_n+1]), _f0(new double[_n+1]), _f1(0), _f2(0), _f3(0), _order(order) {untested(); if (_n < 0) {untested(); throw Exception("no points in spline"); }else{untested(); } for (int i=0; i<=_n; ++i) {untested(); _x[i] = table[static_cast(i)].first; _f0[i] = table[static_cast(i)].second; } // set up h -------------------------------------------------- double* h = new double[_n+1]; for (int i=0; i<_n; ++i) { h[i] = _x[i+1] - _x[i]; if (h[i] == 0.) {untested(); throw Exception("duplicate points in spline: " + to_string(_x[i]) + ", " + to_string(_x[i+1])); }else{untested(); } } h[_n] = NOT_VALID; switch (_order) { case 3: construct_order_3(h, d0, dn); break; case 2: construct_order_2(h, d0, dn); break; case 1: construct_order_1(h, d0, dn); break; case 0: untested(); /* nothing to do */ break; default: untested(); error(bDANGER, "illegal spline order (%d), must be 0, 1, 2, 3\n", _order); break; } } /*--------------------------------------------------------------------------*/ SPLINE::SPLINE(const std::vector, PARAMETER > >& table, double d0, double dn, int order) :_n(static_cast(table.size())-1), _x( new double[_n+1]), _f0(new double[_n+1]), _f1(0), _f2(0), _f3(0), _order(order) { if (_n < 0) { throw Exception("no points in spline"); }else{ } for (int i=0; i<=_n; ++i) { _x[i] = table[static_cast(i)].first; _f0[i] = table[static_cast(i)].second; } // set up h -------------------------------------------------- double* h = new double[_n+1]; for (int i=0; i<_n; ++i) { h[i] = _x[i+1] - _x[i]; if (h[i] == 0.) { throw Exception("duplicate points in spline: " + to_string(_x[i]) + ", " + to_string(_x[i+1])); }else{ } } h[_n] = NOT_VALID; switch (_order) { case 3: construct_order_3(h, d0, dn); break; case 2: construct_order_2(h, d0, dn); break; case 1: construct_order_1(h, d0, dn); break; case 0: untested(); /* nothing to do */ break; default: untested(); error(bDANGER, "illegal spline order (%d), must be 0, 1, 2, 3\n", _order); break; } } /*--------------------------------------------------------------------------*/ void SPLINE::construct_order_1(double* h, double d0, double dn) { assert(_n >= 0); _f1 = h; // reuse storage for (int i=0; i<_n; ++i) { _f1[i] = (_f0[i+1] - _f0[i]) / h[i]; } //h = 0; if (d0 == NOT_INPUT) { _d0 = _f1[0]; }else{untested(); _d0 = d0; } if (dn == NOT_INPUT) { _f1[_n] = _f1[_n-1]; }else{untested(); _f1[_n] = dn; } } /*--------------------------------------------------------------------------*/ void SPLINE::construct_order_2(double* h, double d0, double dn) { assert(_n >= 0); _f1 = new double[_n+1]; if (d0 != NOT_INPUT && dn == NOT_INPUT) { _d0 = _f1[0] = d0; for (int i=0; i<_n; ++i) { _f1[i+1] = 2*(_f0[i+1]-_f0[i])/h[i] - _f1[i]; } }else{ if (dn == NOT_INPUT) { // neither bc .. must guess _f1[_n] = (_f0[_n] - _f0[_n-1]) / h[_n-1]; }else{ _f1[_n] = dn; } for (int i=_n-1; i>=0; --i) { _f1[i] = 2*(_f0[i+1]-_f0[i])/h[i] - _f1[i+1]; } if (d0 == NOT_INPUT) { _d0 = _f1[0]; }else{ // both bc ... discontinuous derivative at _x[0] _d0 = d0; } } // second derivative -- piecewise constant _f2 = h; // reuse storage for (int i=0; i<_n; ++i) { _f2[i] = .5 * (_f1[i+1] - _f1[i]) / h[i]; } _f2[_n] = 0.; //h = 0; } /*--------------------------------------------------------------------------*/ void SPLINE::construct_order_3(double* h, double d0, double dn) { assert(_n >= 0); // set up right side ----------------------------------------- double* b = new double[_n+1]; // b as in Ax=b for (int i=1; i<_n; ++i) { double num = _f0[i+1]*h[i-1] -_f0[i]*(h[i]+h[i-1]) +_f0[i-1]*h[i]; double den = h[i-1] * h[i]; b[i] = 3 * num / den; } // boundary conditions if (d0 == NOT_INPUT) { b[0] = 0.; }else{ b[0] = 3 * ((_f0[1]-_f0[0])/h[0] - d0); } if (dn == NOT_INPUT) { b[_n] = 0.; }else{ b[_n] = 3 * (dn - (_f0[_n]-_f0[_n-1])/h[_n-1]); } // fill, LU decomp, fwd sub ---------------------------------- double* u = new double[_n+1]; double* z = b; // reuse storage. if (d0 == NOT_INPUT) { u[0] = 0.; z[0] = 0.; }else{ u[0] = .5; // h[0] / (2*h[0]) z[0] = b[0] / (2*h[0]); } for (int i=1; i<_n; ++i) { double p = 2*(h[i]+h[i-1]) - h[i-1]*u[i-1]; // pivot u[i] = h[i] / p; z[i] = (b[i] - z[i-1]*h[i-1]) / p; } if (dn == NOT_INPUT) { // natural z[_n] = 0; }else{ // clamped double p = h[_n-1] * (2.-u[_n-1]); z[_n] = (b[_n] - z[_n-1]*h[_n-1]) / p; } u[_n] = NOT_VALID; //b = 0; // back sub -------------------------------------------------- _f1 = u; // reuse storage. _f2 = z; _f3 = h; _f2[_n] = z[_n]; _f3[_n] = 0.; for (int i=_n-1; i>=0; --i) { _f2[i] = z[i] - u[i]*_f2[i+1]; _f1[i] = (_f0[i+1]-_f0[i])/h[i] - h[i]*(_f2[i+1]+2*_f2[i])/3; _f3[i] = (_f2[i+1]-_f2[i])/(3*h[i]); trace4("", i, _f1[i], _f2[i], _f3[i]); } _d0 = fixzero(_f1[0], _f1[1]); //_f1[0]; assert(d0 == NOT_INPUT || _d0 == d0); // set up last slot for extrapolation above. ----------------- if (dn == NOT_INPUT) { // natural _f1[_n] = _f1[_n-1] + (_x[_n]-_x[_n-1])*_f2[_n-1]; }else{ // clamped _f1[_n] = dn; } _f2[_n] = 0.; _f3[_n] = 0.; //u = z = h = 0; } /*--------------------------------------------------------------------------*/ SPLINE::~SPLINE() { delete [] _x; delete [] _f0; delete [] _f1; delete [] _f2; delete [] _f3; } /*--------------------------------------------------------------------------*/ FPOLY1 SPLINE::at(double x)const { assert(_n >= 0); double* here = std::upper_bound(_x, _x+_n+1, x); if (here == _x) { // x out of range, below if (_order == 0) {untested(); return FPOLY1(x, _f0[0], 0.); }else{ double dx = x - _x[0]; double f0 = _f0[0] + dx*_d0; return FPOLY1(x, f0, _d0); } }else{ // x in range, or out of range above int i = static_cast(here - _x - 1); double dx = x - _x[i]; switch (_order) { case 3:{ double f0 = _f0[i] + dx*(_f1[i] + dx*(_f2[i] + dx*_f3[i])); double f1 = _f1[i] + dx*(2*_f2[i] + 3*dx*_f3[i]); return FPOLY1(x, f0, f1); } case 2:{ double f0 = _f0[i] + dx*(_f1[i] + dx*_f2[i]); double f1 = _f1[i] + dx*(2*_f2[i]); return FPOLY1(x, f0, f1); } case 1:{ double f0 = _f0[i] + dx*_f1[i]; double f1 = _f1[i]; return FPOLY1(x, f0, f1); } case 0: untested(); return FPOLY1(x, _f0[i], 0.); default: untested(); assert(!"spline problem"); return FPOLY1(); } untested(); //trace4("", x, _x[i], dx, i); //trace4("", _f0[i], _f1[i], _f2[i], _f3[i]); //trace4("", _f0[i+1], _f1[i+1], _f2[i+1], _f3[i+1]); //trace2("", f0, f1); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ����������������������������������������src/m_spline.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000004760�11454012162�0013627�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_spline.h,v 26.83 2008/06/05 04:46:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * piecewise polynomial interpolation * Constructor args: * table : a vector of xy pairs, all of the data points. * d0, dn: boundary conditions -- value of the first derivative at boundaries. * order : order of interpolating polynomial, must be in {0, 1, 2, 3}. * * Outside the range, the result is linearly extrapolated with slope d0, dn. * ("clamped" splines) * * If d0 or dn is set to NOT_INPUT, it is a "natural" spline, with the * derivative being determined by the data. * See any numerical analysis text for explanation. */ //testing=trivial 2006.07.17 #ifndef M_SPLINE_H #define M_SPLINE_H #include "u_parameter.h" /*--------------------------------------------------------------------------*/ class FPOLY1; /*--------------------------------------------------------------------------*/ class INTERFACE SPLINE { private: int _n; double* _x; double* _f0; double* _f1; double* _f2; double* _f3; int _order; double _d0; void construct_order_3(double* h, double d0, double dn); void construct_order_2(double* h, double d0, double dn); void construct_order_1(double* h, double d0, double dn); public: SPLINE(const std::vector& table, double d0, double dn, int order); SPLINE(const std::vector,PARAMETER > >& table, double d0, double dn, int order); ~SPLINE(); FPOLY1 at(double x)const; }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ����������������src/m_wave.h����������������������������������������������������������������������������������������0000664�0000000�0000000�00000011232�11454012162�0013267�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: m_wave.h,v 26.86 2008/07/07 22:31:11 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * "wave" class, for transmission lines and delays */ //testing=script 2006.07.13 #include "l_denoise.h" #include "m_interp.h" /*--------------------------------------------------------------------------*/ class WAVE { private: std::deque _w; double _delay; explicit WAVE(const WAVE&) {unreachable();} public: typedef std::deque::iterator iterator; typedef std::deque::const_iterator const_iterator; explicit WAVE(double d=0); ~WAVE() {} WAVE& set_delay(double d); WAVE& initialize(); WAVE& push(double t, double v); FPOLY1 v_out(double t)const; double v_reflect(double t, double v_total)const; WAVE& operator+=(const WAVE& x); WAVE& operator+=(double x); WAVE& operator*=(const WAVE& x); WAVE& operator*=(double x); const_iterator begin()const {return _w.begin();} const_iterator end()const {return _w.end();} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ // push: insert a signal on the "input" end. // args: t = the time now // v = the value to push // inline WAVE& WAVE::push(double t, double v) { _w.push_back(DPAIR(t+_delay, v)); return *this; } /*--------------------------------------------------------------------------*/ // initialize: remove all info, fill it with all 0. // inline WAVE& WAVE::initialize() { _w.clear(); return *this; } /*--------------------------------------------------------------------------*/ // constructor -- argument is the delay // inline WAVE::WAVE(double d) :_w(), _delay(d) { initialize(); } /*--------------------------------------------------------------------------*/ inline WAVE& WAVE::set_delay(double d) { _delay = d; return *this; } /*--------------------------------------------------------------------------*/ // v_out: return the value at the "output" end // args: t = the time now // inline FPOLY1 WAVE::v_out(double t)const { return interpolate(_w.begin(), _w.end(), t, 0., 0.); } /*--------------------------------------------------------------------------*/ // reflect: calculate a reflection // args: t = the time now // v_total = actual voltage across the termination // returns: the value (voltage) to send back as the reflection // inline double WAVE::v_reflect(double t, double v_total)const { // return (v_total*2 - v_out(t)); // de-noised return dn_diff(v_total*2, v_out(t).f0); } /*--------------------------------------------------------------------------*/ inline WAVE& WAVE::operator+=(const WAVE& x) { untested(); for (std::deque::iterator i = _w.begin(); i != _w.end(); ++i) { untested(); (*i).second += x.v_out((*i).first).f0; } return *this; } /*--------------------------------------------------------------------------*/ inline WAVE& WAVE::operator+=(double x) { untested(); for (std::deque::iterator i = _w.begin(); i != _w.end(); ++i) { untested(); (*i).second += x; } return *this; } /*--------------------------------------------------------------------------*/ inline WAVE& WAVE::operator*=(const WAVE& x) { untested(); for (std::deque::iterator i = _w.begin(); i != _w.end(); ++i) { untested(); (*i).second *= x.v_out((*i).first).f0; } return *this; } /*--------------------------------------------------------------------------*/ inline WAVE& WAVE::operator*=(double x) { untested(); for (std::deque::iterator i = _w.begin(); i != _w.end(); ++i) { untested(); (*i).second *= x; } return *this; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/main.cc�����������������������������������������������������������������������������������������0000664�0000000�0000000�00000015713�11454012162�0013103�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: main.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * top level module * it all starts here */ //testing=script 2006.07.14 #include "e_cardlist.h" #include "u_lang.h" #include "ap.h" #include "patchlev.h" #include "c_comand.h" #include "declare.h" /* plclose */ /*--------------------------------------------------------------------------*/ struct JMP_BUF{ sigjmp_buf p; } env; /*--------------------------------------------------------------------------*/ static void sign_on(void) { IO::mstdout << "Gnucap " PATCHLEVEL "\n" "The Gnu Circuit Analysis Package\n" "Never trust any version less than 1.0\n" "Copyright 1982-2009, Albert Davis\n" "Gnucap comes with ABSOLUTELY NO WARRANTY\n" "This is free software, and you are welcome\n" "to redistribute it under the terms of \n" "the GNU General Public License, version 3 or later.\n" "See the file \"COPYING\" for details.\n"; } /*--------------------------------------------------------------------------*/ static void read_startup_files(void) { std::string name = findfile(SYSTEMSTARTFILE, SYSTEMSTARTPATH, R_OK); if (name != "") {untested(); CMD::command("get " + name, &CARD_LIST::card_list); }else{ } name = findfile(USERSTARTFILE, USERSTARTPATH, R_OK); if (name != "") {untested(); CMD::command("get " + name, &CARD_LIST::card_list); }else{ } CMD::command("clear", &CARD_LIST::card_list); if (!OPT::language) { CMD::command(std::string("options lang=") + DEFAULT_LANGUAGE, &CARD_LIST::card_list); }else{ } } /*--------------------------------------------------------------------------*/ /* sig_abrt: trap asserts */ extern "C" { static void sig_abrt(SIGNALARGS) {itested(); signal(SIGINT,sig_abrt); static int count = 10; if (--count > 0) {itested(); error(bDANGER, "\n"); }else{untested(); exit(1); } } } /*--------------------------------------------------------------------------*/ /* sig_int: what to do on receipt of interrupt signal (SIGINT) * cancel batch files, then back to command mode. * (actually, control-c trap) */ extern "C" { static void sig_int(SIGNALARGS) { signal(SIGINT,sig_int); if (ENV::run_mode == rBATCH) {untested(); exit(1); }else{ IO::error << '\n'; siglongjmp(env.p,1); } } } /*--------------------------------------------------------------------------*/ extern "C" { static void sig_fpe(SIGNALARGS) { untested(); signal(SIGFPE,sig_fpe); error(bDANGER, "floating point error\n"); } } /*--------------------------------------------------------------------------*/ static void setup_traps(void) { signal(SIGFPE,sig_fpe); signal(SIGINT,sig_int); signal(SIGABRT,sig_abrt); } /*--------------------------------------------------------------------------*/ /* finish: clean up after a command * deallocates space, closes plot windows, resets i/o redirection, etc. * This is done separately for exception handling. * If a command aborts, clean-up is still done, leaving a consistent state. * //BUG// It is a function to call as a remnant of old C code. * Should be in a destructor, so it doesn't need to be explicitly called. */ static void finish(void) { plclose(); outreset(); } /*--------------------------------------------------------------------------*/ static void process_cmd_line(int argc, const char *argv[]) { for (int ii = 1; ii < argc; /*inside*/) { try { if (strcasecmp(argv[ii], "-i") == 0) {itested(); ++ii; if (ii < argc) {itested(); CMD::command(std::string("include ") + argv[ii++], &CARD_LIST::card_list); }else{untested(); } }else if (strcasecmp(argv[ii], "-c") == 0) {itested(); ++ii; if (ii < argc) {itested(); CS cmd(CS::_STRING, argv[ii++]); // command line CMD::cmdproc(cmd, &CARD_LIST::card_list); }else{untested(); } }else if (strcasecmp(argv[ii], "-b") == 0) { try { ++ii; if (ii < argc) { CMD::command(std::string("< ") + argv[ii++], &CARD_LIST::card_list); }else{untested(); CMD::command(std::string("< /dev/stdin"), &CARD_LIST::card_list); } }catch (Exception& e) { error(bDANGER, e.message() + '\n'); finish(); } if (ii >= argc) { CMD::command("end", &CARD_LIST::card_list); }else{untested(); } }else if (strcasecmp(argv[ii], "-a") == 0) {itested(); ++ii; if (ii < argc) {itested(); CMD::command(std::string("attach ") + argv[ii++], &CARD_LIST::card_list); }else{untested(); } }else{itested(); CMD::command(std::string("include ") + argv[ii++], &CARD_LIST::card_list); } }catch (Exception& e) {itested(); error(bDANGER, e.message() + '\n'); finish(); } } } /*--------------------------------------------------------------------------*/ int main(int argc, const char *argv[]) { { SET_RUN_MODE xx(rBATCH); sign_on(); if (!sigsetjmp(env.p, true)) { try { read_startup_files(); setup_traps(); process_cmd_line(argc,argv); }catch (Exception& e) {untested(); error(bDANGER, e.message() + '\n'); finish(); /* error clean up (from longjmp()) */ CMD::command("quit", &CARD_LIST::card_list); unreachable(); exit(0); } }else{ finish(); /* error clean up (from longjmp()) */ CMD::command("quit", &CARD_LIST::card_list); exit(0); } } {itested(); SET_RUN_MODE xx(rINTERACTIVE); CS cmd(CS::_STDIN); for (;;) {itested(); if (!sigsetjmp(env.p, true)) {itested(); try { if (OPT::language) { OPT::language->parse_top_item(cmd, &CARD_LIST::card_list); }else{ CMD::cmdproc(cmd.get_line(I_PROMPT), &CARD_LIST::card_list); } }catch (Exception_End_Of_Input& e) {itested(); error(bDANGER, e.message() + '\n'); finish(); CMD::command("quit", &CARD_LIST::card_list); exit(0); }catch (Exception& e) {itested(); error(bDANGER, e.message() + '\n'); finish(); } }else{itested(); finish(); /* error clean up (from longjmp()) */ } } } unreachable(); return 0; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������src/md.h��������������������������������������������������������������������������������������������0000664�0000000�0000000�00000014760�11454012162�0012422�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: md.h,v 26.112 2009/07/24 00:10:32 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Machine dependent, configuration, and standard includes */ //testing=trivial 2006.07.17 #ifndef MD_H_INCLUDED #define MD_H_INCLUDED /*--------------------------------------------------------------------------*/ /* autoconf stuff */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /*--------------------------------------------------------------------------*/ /* std collection of includes */ // system #include #include #include #include #include #include #include #include #include #include #include #include #include // types #include #include // containers #include #include #include #include #include // algorithms #include #include /* usual but non-standard (POSIX??) collection of includes */ #include /* chdir, access, getcwd */ #include /* old style unix files */ /*--------------------------------------------------------------------------*/ /* constants related to memory size, word size, etc */ enum { BUFLEN = 256, BIGBUFLEN = 4096 }; /*--------------------------------------------------------------------------*/ /* user interface preferences */ #define I_PROMPT "gnucap> " #define CKT_PROMPT ">" #define ANTI_COMMENT "*>" #define DEFAULT_LANGUAGE "acs" /*--------------------------------------------------------------------------*/ #if defined(__WIN32__) #define ENDDIR "/\\" #define PATHSEP ';' #define SYSTEMSTARTFILE "gnucap.rc" #define SYSTEMSTARTPATH OS::getenv("PATH") #define USERSTARTFILE "gnucap.rc" #define USERSTARTPATH OS::getenv("HOME") #define STEPFILE "/tmp/SXXXXXX" #define SHELL OS::getenv("COMSPEC") /*--------------------------------------------------------------------------*/ #else #define ENDDIR "/" #define PATHSEP ':' #define SYSTEMSTARTFILE "gnucap.rc" #define SYSTEMSTARTPATH OS::getenv("PATH") #define USERSTARTFILE ".gnucaprc" #define USERSTARTPATH OS::getenv("HOME") #define STEPFILE "/tmp/SXXXXXX" #define SHELL OS::getenv("SHELL") #endif /*--------------------------------------------------------------------------*/ /* machine and compiler patches */ #if defined(__MINGW32__) #define SIGSETJMP_IS_BROKEN #define MS_DLL #endif /*--------------------------------------------------------------------------*/ /* some convenient names */ typedef std::complex COMPLEX; typedef std::pair DPAIR; /*--------------------------------------------------------------------------*/ // dynamic cast kluge. // Strictly, this should always be dynamic_cast, but if it has already // been checked, don't bother checking again, hence static_cast. // It works and is faster. #if defined(NDEBUG) #define prechecked_cast static_cast #else #define prechecked_cast dynamic_cast #endif /*--------------------------------------------------------------------------*/ /* portability hacks */ #if !defined(MS_DLL) // The usual way for POSIX compliant systems #include #define INTERFACE #else // Microsoft DLL hacks -- thanks to Holger Vogt and Cesar Strauss for the info // Make the MS DLL functions look like the posix ones. #include #undef min #undef max #undef INTERFACE #ifdef MAKE_DLL #define INTERFACE __declspec(dllimport) #else #define INTERFACE __declspec(dllexport) #endif inline void* dlopen(const char* f, int) { return LoadLibrary(const_cast(f)); } inline void dlclose(void* h) { FreeLibrary((HINSTANCE)h); } inline char* dlerror() { static LPVOID lpMsgBuf = NULL; // free the error message buffer if (lpMsgBuf) { LocalFree(lpMsgBuf); } // get the error code DWORD dw = GetLastError(); // get the corresponding error message FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); return (char*)lpMsgBuf; } #define RTLD_LAZY 0x00001 /* Lazy function call binding. */ #define RTLD_NOW 0x00002 /* Immediate function call binding. */ #define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */ #define RTLD_NOLOAD 0x00004 /* Do not load the object. */ #define RTLD_DEEPBIND 0x00008 /* Use deep binding. */ #define RTLD_GLOBAL 0x00100 #define RTLD_LOCAL 0 #define RTLD_NODELETE 0x01000 #endif #if defined(SIGSETJMP_IS_BROKEN) #undef sigjmp_buf #undef siglongjmp #undef sigsetjmp #define sigjmp_buf jmp_buf #define siglongjmp(a,b) longjmp(a,b) #define sigsetjmp(a,b) setjmp(a) #endif #if !defined(SIGNALARGS) #define SIGNALARGS int #endif /*--------------------------------------------------------------------------*/ /* temporary hacks */ enum RUN_MODE { rPRE_MAIN, /* it hasn't got to main yet */ rPRESET, /* do set up commands now, but not simulation */ /* store parameters, so bare invocation of a */ /* simulation command will do it this way. */ rINTERACTIVE, /* run the commands, interactively */ rSCRIPT, /* execute now, as a command, then restore mode */ rBATCH /* execute now, as a command, then exit */ }; class INTERFACE ENV { public: static RUN_MODE run_mode; // variations on handling of dot commands }; /*--------------------------------------------------------------------------*/ /* my standard collection of includes */ #include "io_trace.h" #include "io_error.h" /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ����������������src/measure_at.cc�����������������������������������������������������������������������������������0000664�0000000�0000000�00000004502�11454012162�0014276�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: measure_at.cc,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2008 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ #include "u_parameter.h" #include "m_wave.h" #include "u_function.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class MEASURE : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { std::string probe_name; PARAMETER x; bool derivative = false; unsigned here = Cmd.cursor(); Cmd >> probe_name; WAVE* w = find_wave(probe_name); if (!w) { Cmd.reset(here); }else{ } here = Cmd.cursor(); do { ONE_OF || Get(Cmd, "probe", &probe_name) || Get(Cmd, "x", &x) || Get(Cmd, "at", &x) || Get(Cmd, "deriv{ative}", &derivative) ; }while (Cmd.more() && !Cmd.stuck(&here)); if (!w) { w = find_wave(probe_name); }else{ } if (w) { x.e_val(BIGBIG, Scope); return to_string((derivative) ? (w->v_out(x).f1) : (w->v_out(x).f0)); }else{ throw Exception_No_Match(probe_name); } } } p1; DISPATCHER::INSTALL d1(&measure_dispatcher, "at", &p1); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/measure_average.cc������������������������������������������������������������������������������0000664�0000000�0000000�00000005463�11454012162�0015313�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: measure_average.cc,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2008 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ #include "u_parameter.h" #include "m_wave.h" #include "u_function.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class MEASURE : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { std::string probe_name; PARAMETER before(BIGBIG); PARAMETER after(-BIGBIG); unsigned here = Cmd.cursor(); Cmd >> probe_name; WAVE* w = find_wave(probe_name); if (!w) { Cmd.reset(here); }else{ } here = Cmd.cursor(); do { ONE_OF || Get(Cmd, "probe", &probe_name) || Get(Cmd, "before", &before) || Get(Cmd, "after", &after) || Get(Cmd, "end", &before) || Get(Cmd, "begin", &after) ; }while (Cmd.more() && !Cmd.stuck(&here)); if (!w) { w = find_wave(probe_name); }else{ } if (w) { before.e_val(BIGBIG, Scope); after.e_val(-BIGBIG, Scope); WAVE::const_iterator begin = lower_bound(w->begin(), w->end(), DPAIR(after, -BIGBIG)); WAVE::const_iterator end = upper_bound(w->begin(), w->end(), DPAIR(before, BIGBIG)); WAVE::const_iterator lower = begin; double area = 0; WAVE::const_iterator i = begin; while (++i < end) { area += .5 * (lower->second + i->second) * (i->first - lower->first); lower = i; } return to_string(area/(lower->first - begin->first)); }else{ throw Exception_No_Match(probe_name); } } } p4; DISPATCHER::INSTALL d4(&measure_dispatcher, "average|mean", &p4); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/measure_cross.cc��������������������������������������������������������������������������������0000664�0000000�0000000�00000007066�11454012162�0015033�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: measure_cross.cc,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2008 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ #include "u_parameter.h" #include "m_wave.h" #include "u_function.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class MEASURE : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { std::string probe_name; PARAMETER before(BIGBIG); PARAMETER after(-BIGBIG); PARAMETER cross(0.); int slope = 1; bool last = false; unsigned here = Cmd.cursor(); Cmd >> probe_name; WAVE* w = find_wave(probe_name); if (!w) { Cmd.reset(here); }else{ } here = Cmd.cursor(); do { ONE_OF || Get(Cmd, "probe", &probe_name) || Get(Cmd, "before", &before) || Get(Cmd, "after", &after) || Get(Cmd, "end", &before) || Get(Cmd, "begin", &after) || Get(Cmd, "cross", &cross) || Set(Cmd, "rise", &slope, 1) || Set(Cmd, "fall", &slope, -1) || Set(Cmd, "last", &last, true) || Set(Cmd, "first", &last, false) ; }while (Cmd.more() && !Cmd.stuck(&here)); if (!w) { w = find_wave(probe_name); }else{ } if (w) { before.e_val(BIGBIG, Scope); after.e_val(-BIGBIG, Scope); cross.e_val(0., Scope); double cross1 = cross * slope; enum STAT {WAITING, READY, DONE} stat = WAITING; double x_time = (last) ? -BIGBIG : BIGBIG; WAVE::const_iterator begin = lower_bound(w->begin(), w->end(), DPAIR(after, -BIGBIG)); WAVE::const_iterator end = upper_bound(w->begin(), w->end(), DPAIR(before, BIGBIG)); WAVE::const_iterator lower = begin; for (WAVE::const_iterator i = begin; i < end && stat != DONE; ++i) { double val = i->second * slope; switch (stat) { case WAITING: if (val < cross1) { stat = READY; lower = i; }else{ } break; case READY: if (val > cross1) { stat = (last) ? WAITING : DONE; WAVE::const_iterator upper = i; double position = (cross1*slope - lower->second) / (upper->second - lower->second); x_time = lower->first + position * (upper->first - lower->first); }else{ lower = i; } break; case DONE: break; }; } return to_string(x_time); }else{ throw Exception_No_Match(probe_name); } } } p4; DISPATCHER::INSTALL d4(&measure_dispatcher, "cross", &p4); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/measure_eval.cc���������������������������������������������������������������������������������0000664�0000000�0000000�00000003402�11454012162�0014617�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: measure_eval.cc,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2008 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ #include "u_parameter.h" //#include "globals.h" //#include "m_wave.h" #include "u_function.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class MEASURE : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { PARAMETER arg; Cmd >> arg; arg.e_val(BIGBIG, Scope); return to_string(double(arg)); } } p1; DISPATCHER::INSTALL d1(&measure_dispatcher, "eval", &p1); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/measure_integral.cc�����������������������������������������������������������������������������0000664�0000000�0000000�00000005433�11454012162�0015503�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: measure_integral.cc,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2008 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ #include "u_parameter.h" #include "m_wave.h" #include "u_function.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class MEASURE : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { std::string probe_name; PARAMETER before(BIGBIG); PARAMETER after(-BIGBIG); unsigned here = Cmd.cursor(); Cmd >> probe_name; WAVE* w = find_wave(probe_name); if (!w) { Cmd.reset(here); }else{ } here = Cmd.cursor(); do { ONE_OF || Get(Cmd, "probe", &probe_name) || Get(Cmd, "before", &before) || Get(Cmd, "after", &after) || Get(Cmd, "end", &before) || Get(Cmd, "begin", &after) ; }while (Cmd.more() && !Cmd.stuck(&here)); if (!w) { w = find_wave(probe_name); }else{ } if (w) { before.e_val(BIGBIG, Scope); after.e_val(-BIGBIG, Scope); WAVE::const_iterator begin = lower_bound(w->begin(), w->end(), DPAIR(after, -BIGBIG)); WAVE::const_iterator end = upper_bound(w->begin(), w->end(), DPAIR(before, BIGBIG)); WAVE::const_iterator lower = begin; double area = 0; for (WAVE::const_iterator i = begin; ++i < end; ) { area += .5 * (lower->second + i->second) * (i->first - lower->first); lower = i; } return to_string(area); }else{ throw Exception_No_Match(probe_name); } } } p4; DISPATCHER::INSTALL d4(&measure_dispatcher, "integrate|integral|area", &p4); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/measure_max.cc����������������������������������������������������������������������������������0000664�0000000�0000000�00000005714�11454012162�0014465�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: measure_max.cc,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2008 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ #include "u_parameter.h" #include "m_wave.h" #include "u_function.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class MEASURE : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { std::string probe_name; PARAMETER before(BIGBIG); PARAMETER after(-BIGBIG); bool last = false; bool arg = false; unsigned here = Cmd.cursor(); Cmd >> probe_name; WAVE* w = find_wave(probe_name); if (!w) { Cmd.reset(here); }else{ } here = Cmd.cursor(); do { ONE_OF || Get(Cmd, "probe", &probe_name) || Get(Cmd, "before", &before) || Get(Cmd, "after", &after) || Get(Cmd, "end", &before) || Get(Cmd, "begin", &after) || Set(Cmd, "arg", &arg, true) || Set(Cmd, "last", &last, true) || Set(Cmd, "first", &last, false) ; }while (Cmd.more() && !Cmd.stuck(&here)); if (!w) { w = find_wave(probe_name); }else{ } if (w) { before.e_val(BIGBIG, Scope); after.e_val(-BIGBIG, Scope); double time = (last) ? -BIGBIG : BIGBIG; double m = -BIGBIG; WAVE::const_iterator begin = lower_bound(w->begin(), w->end(), DPAIR(after, -BIGBIG)); WAVE::const_iterator end = upper_bound(w->begin(), w->end(), DPAIR(before, BIGBIG)); for (WAVE::const_iterator i = begin; i < end; ++i) { double val = i->second; if (val > m || (last && (val == m))) { time = i->first; m = val; }else{ } } return to_string((arg) ? (time) : (m)); }else{ throw Exception_No_Match(probe_name); } } } p1; DISPATCHER::INSTALL d1(&measure_dispatcher, "max", &p1); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ����������������������������������������������������src/measure_min.cc����������������������������������������������������������������������������������0000664�0000000�0000000�00000005713�11454012162�0014462�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: measure_min.cc,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2008 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ #include "u_parameter.h" #include "m_wave.h" #include "u_function.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class MEASURE : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { std::string probe_name; PARAMETER before(BIGBIG); PARAMETER after(-BIGBIG); bool last = false; bool arg = false; unsigned here = Cmd.cursor(); Cmd >> probe_name; WAVE* w = find_wave(probe_name); if (!w) { Cmd.reset(here); }else{ } here = Cmd.cursor(); do { ONE_OF || Get(Cmd, "probe", &probe_name) || Get(Cmd, "before", &before) || Get(Cmd, "after", &after) || Get(Cmd, "end", &before) || Get(Cmd, "begin", &after) || Set(Cmd, "arg", &arg, true) || Set(Cmd, "last", &last, true) || Set(Cmd, "first", &last, false) ; }while (Cmd.more() && !Cmd.stuck(&here)); if (!w) { w = find_wave(probe_name); }else{ } if (w) { before.e_val(BIGBIG, Scope); after.e_val(-BIGBIG, Scope); double time = (last) ? -BIGBIG : BIGBIG; double m = BIGBIG; WAVE::const_iterator begin = lower_bound(w->begin(), w->end(), DPAIR(after, -BIGBIG)); WAVE::const_iterator end = upper_bound(w->begin(), w->end(), DPAIR(before, BIGBIG)); for (WAVE::const_iterator i = begin; i < end; ++i) { double val = i->second; if (val < m || (last && (val == m))) { time = i->first; m = val; }else{ } } return to_string((arg) ? (time) : (m)); }else{ throw Exception_No_Match(probe_name); } } } p2; DISPATCHER::INSTALL d2(&measure_dispatcher, "min", &p2); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������src/measure_rms.cc����������������������������������������������������������������������������������0000664�0000000�0000000�00000005507�11454012162�0014501�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: measure_rms.cc,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2008 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ #include "u_parameter.h" #include "m_wave.h" #include "u_function.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class MEASURE : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { std::string probe_name; PARAMETER before(BIGBIG); PARAMETER after(-BIGBIG); unsigned here = Cmd.cursor(); Cmd >> probe_name; WAVE* w = find_wave(probe_name); if (!w) { Cmd.reset(here); }else{ } here = Cmd.cursor(); do { ONE_OF || Get(Cmd, "probe", &probe_name) || Get(Cmd, "before", &before) || Get(Cmd, "after", &after) || Get(Cmd, "end", &before) || Get(Cmd, "begin", &after) ; }while (Cmd.more() && !Cmd.stuck(&here)); if (!w) { w = find_wave(probe_name); }else{ } if (w) { before.e_val(BIGBIG, Scope); after.e_val(-BIGBIG, Scope); WAVE::const_iterator begin = lower_bound(w->begin(), w->end(), DPAIR(after, -BIGBIG)); WAVE::const_iterator end = upper_bound(w->begin(), w->end(), DPAIR(before, BIGBIG)); WAVE::const_iterator lower = begin; double area = 0; WAVE::const_iterator i = begin; while (++i < end) { area += .5 * (lower->second*lower->second + i->second*i->second) * (i->first - lower->first); lower = i; } return to_string(sqrt(area/(lower->first - begin->first))); }else{ throw Exception_No_Match(probe_name); } } } p4; DISPATCHER::INSTALL d4(&measure_dispatcher, "rms", &p4); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/measure_slewrate.cc�����������������������������������������������������������������������������0000664�0000000�0000000�00000012427�11454012162�0015525�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: measure_slewrate.cc,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2008 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ #include "l_compar.h" #include "u_parameter.h" #include "m_wave.h" #include "u_function.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class MEASURE : public FUNCTION { public: std::string eval(CS& Cmd, const CARD_LIST* Scope)const { std::string probe_name; PARAMETER before(BIGBIG); PARAMETER after(-BIGBIG); PARAMETER start_val; PARAMETER stop_val; bool last = false; bool expression = false; unsigned here = Cmd.cursor(); Cmd >> probe_name; WAVE* w = find_wave(probe_name); if (!w) { Cmd.reset(here); }else{ } here = Cmd.cursor(); do { ONE_OF || Get(Cmd, "probe", &probe_name) || Get(Cmd, "before", &before) || Get(Cmd, "after", &after) || Get(Cmd, "end", &before) || Get(Cmd, "begin", &after) || Get(Cmd, "initial", &start_val) || Get(Cmd, "final", &stop_val) || Get(Cmd, "start_val", &start_val) || Get(Cmd, "to", &stop_val) || Set(Cmd, "last", &last, true) || Set(Cmd, "first", &last, false) || Set(Cmd, "expr{ession}",&expression, true) ; }while (Cmd.more() && !Cmd.stuck(&here)); if (!w) { w = find_wave(probe_name); }else{ } if (w) { before.e_val(BIGBIG, Scope); after.e_val(-BIGBIG, Scope); start_val.e_val(0., Scope); stop_val.e_val(0., Scope); enum STAT {WAITING, READY, IN_RANGE, DONE} stat = WAITING; double try_start_time = BIGBIG; double start_time = BIGBIG; double stop_time = BIGBIG; WAVE::const_iterator begin = lower_bound(w->begin(), w->end(), DPAIR(after, -BIGBIG)); WAVE::const_iterator end = upper_bound(w->begin(), w->end(), DPAIR(before, BIGBIG)); WAVE::const_iterator lower = begin; for (WAVE::const_iterator i = begin; i < end && stat != DONE; ++i) { double val = i->second; switch (stat) { case WAITING: if (in_order(val, double(start_val), double(stop_val))) { stat = READY; }else{ // still WAITING } break; case READY: if (in_order(val, double(start_val), double(stop_val))) { // still READY }else if (in_order(double(start_val), val, double(stop_val))) { stat = IN_RANGE; WAVE::const_iterator upper = i; double position = (start_val - lower->second) / (upper->second - lower->second); try_start_time = lower->first + position * (upper->first - lower->first); }else if (in_order(double(start_val), double(stop_val), val)) { // not accurate, was never IN_RANGE stat = DONE; double position = (start_val - lower->second) / (i->second - lower->second); start_time = lower->first + position * (i->first - lower->first); position = (stop_val - lower->second) / (i->second - lower->second); stop_time = lower->first + position * (i->first - lower->first); }else{untested(); // something is wrong } break; case IN_RANGE: if (in_order(val, double(start_val), double(stop_val))) { // false start stat = READY; }else if (in_order(double(start_val), val, double(stop_val))) { // still IN_RANGE }else if (in_order(double(start_val), double(stop_val), val)) { stat = (last) ? WAITING : DONE; start_time = try_start_time; double position = (stop_val - lower->second) / (i->second - lower->second); stop_time = lower->first + position * (i->first - lower->first); }else{untested(); // something is wrong } break; case DONE: break; }; lower = i; } if (stop_time < BIGBIG) { assert(stop_time > start_time); if (expression) { return "((" + to_string(stop_val) + "-" + to_string(start_val) + ")/(" + to_string(stop_time) + "-" + to_string(start_time) + "))"; }else{ return to_string((stop_val-start_val)/(stop_time-start_time)); } }else{ return to_string(BIGBIG); } }else{ throw Exception_No_Match(probe_name); } } } p3; DISPATCHER::INSTALL d3(&measure_dispatcher, "ddt|slewrate|slope", &p3); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/mode.h������������������������������������������������������������������������������������������0000664�0000000�0000000�00000005650�11454012162�0012744�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: mode.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * several enumerated types to identify various modes */ //testing=script,complete 2006.07.14 #ifndef MODE_H #define MODE_H #include "io_.h" /*--------------------------------------------------------------------------*/ enum smode_t {moUNKNOWN=0, moANALOG=1, moDIGITAL, moMIXED}; inline OMSTREAM& operator<<(OMSTREAM& o, smode_t t) { const std::string s[] = {"unknown", "analog", "digital", "mixed"}; assert(t >= int(moUNKNOWN)); assert(t <= int(moMIXED)); return (o << s[t]); } enum SIM_MODE { // simulation types s_NONE, /* not doing anything, reset by cmd interpreter */ s_AC, /* AC analysis */ s_OP, /* op command */ s_DC, /* dc sweep command */ s_TRAN, /* transient command */ s_FOURIER /* fourier command */ }; const int sSTART = s_NONE; const int sCOUNT = s_FOURIER + 1; inline OMSTREAM& operator<<(OMSTREAM& o, SIM_MODE t) { const std::string s[] = {"ALL", "AC", "OP", "DC", "TRAN", "FOURIER"}; assert(t >= int(s_NONE)); assert(t <= int(s_FOURIER)); return (o << s[t]); } enum SIM_PHASE { // which of the many steps... p_NONE, /* not doing anything, reset by cmd interpreter */ p_INIT_DC, /* initial DC analysis */ p_DC_SWEEP, /* DC analysis sweep, in progress */ p_TRAN, /* transient, in progress */ p_RESTORE /* transient restore after stop */ }; enum PROBE_INDEX { // iter probes (continue after SIM_MODE) iPRINTSTEP = sCOUNT, /* iterations for this printed step */ iSTEP, /* iterations this internal step */ iTOTAL /* total iterations since startup */ }; const int iCOUNT = iTOTAL + 1; /* number of iteration counters */ /* control probes */ #define cSTEPCAUSE (0) /* what caused this time step */ #define cSTEPS (1) /* count of hidden steps (+ this unhidden) */ #define cCOUNT (2) /* number of control probes */ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ����������������������������������������������������������������������������������������src/patchlev.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000000053�11454012162�0013616�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define PATCHLEVEL "2009.12.07 RCS 26.136" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/plot.cc�����������������������������������������������������������������������������������������0000664�0000000�0000000�00000017037�11454012162�0013136�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: plot.cc,v 26.110 2009/05/28 15:32:04 al Exp $ * (this file is a mess. it should be redone.) */ //testing=script 2006.07.17 #include "declare.h" /* self */ #include "constant.h" #include "u_opt.h" #include "u_prblst.h" /*--------------------------------------------------------------------------*/ void plottr(double,const PROBELIST&); int plopen(double,double,const PROBELIST&); void plclose(void); void plclear(void); static void plborder(void); static void calibrate(const PROBE&); static int round_to_int(double); static void plhead(const PROBELIST&); static int point(double,double,double,int,int,int); static void plotarg(double,double,double,double,double,double, double,double,double); /*--------------------------------------------------------------------------*/ #define MAXWIDTH 512 #define OUTWIDTH (std::min(static_cast(OPT::outwidth), MAXWIDTH)) #define INDENT 8 /* beware OMSTERAM::form! */ #define CONSSCALE (OUTWIDTH - INDENT - 2) /*console scale size in chr */ static bool active; /* flag: plotting has opened */ static double xstart, xstop; static char border[MAXWIDTH+1]; /* border string (keep, repeat at end) */ static char emptydata[MAXWIDTH+1]; /* empty data, to copy then insert data */ /*--------------------------------------------------------------------------*/ void plottr(double xx, const PROBELIST& plotlist) /* plot a data point, */ { if (active) { int ii = 0; double lo[2] = {0.}; double hi[2] = {0.}; double val[2] = {0.}; for (PROBELIST::const_iterator i = plotlist.begin(); i != plotlist.end(); ++i) { val[ii] = i->value(); if (i->range() != 0.) { lo[ii] = i->lo(); hi[ii] = i->hi(); }else{ lo[ii] = -5.; hi[ii] = 5.; } ++ii; if (ii >= 2) { break; } } if (ii <= 1) { val[1] = NOT_VALID; } plotarg(xx, val[0], val[1], xstart, lo[0], lo[1], xstop, hi[0], hi[1]); } } /*--------------------------------------------------------------------------*/ /* plopen: begin the plot. any type */ int plopen(double start, double stop, const PROBELIST& plotlist) { if (start == stop) { IO::plotout = OMSTREAM(); } if (!IO::plotout.any()) { plclear(); return false; } xstart = start; xstop = stop; plhead(plotlist); assert(active == false); active = true; return true; } /*--------------------------------------------------------------------------*/ /* plclose: finish up the plot (any type) */ void plclose(void) { if (!active) { return; } plborder(); active = false; IO::plotout = OMSTREAM(); } /*--------------------------------------------------------------------------*/ /* plclear: clear graphics mode */ void plclear(void) { if (active) { untested(); } active = false; } /*--------------------------------------------------------------------------*/ /* plborder: draw the border -- Ascii graphics */ static void plborder(void) { IO::plotout.tab(INDENT) << border << '\n'; } /*--------------------------------------------------------------------------*/ /* calibrate: calibrate the y axis. ascii plot. */ static void calibrate(const PROBE& prb) { static char nums[20]; /* this label string */ static char highs[20]; /* the last label string */ int cal; /* char position within line */ int stop; /* location of last label, stop printing */ int filled; /* how far (characters) have been printed */ int numsize; /* number of characters in this label */ int start; /* starting position of this label */ double markno; /* loop counter */ double hi, lo; if (prb.range() == 0) { hi = 5; lo = -5; }else{ hi = prb.hi(); lo = prb.lo(); } double range = hi - lo; strcpy(highs, ftos(hi, 0, 5, IO::formaat)); highs[8] = '\0'; /* trim to 8 chrs */ /* *strchr(&highs[2],' ') = '\0'; */ /* make the top label, and save */ stop = OUTWIDTH - static_cast(strlen(highs)) - 1; /* space for it. */ IO::plotout << prb.label(); range = hi - lo; filled = 0; for (markno = 0.; markno < OPT::ydivisions; markno++) { double number = lo + range * markno/OPT::ydivisions ; if (std::abs(number) < std::abs(range)/(10.*CONSSCALE)) { number = 0.; } /* label to put on this div. */ strcpy(nums, ftos(number, 0, 5, IO::formaat)); nums[8] = '\0'; /* trim to 8 chrs */ numsize = static_cast(strlen(nums)); /* center it over the mark */ cal = round_to_int(INDENT + CONSSCALE * (markno/OPT::ydivisions)); start = cal - (numsize+1)/2; if (start > filled && start+numsize < stop) { IO::plotout.tab(start) << nums; /* if it fits, print it */ filled = start + numsize ; }else{untested(); } } IO::plotout.tab(stop) << highs << '\n'; /* print the last calibration */ } /*--------------------------------------------------------------------------*/ static int round_to_int(double x) { return static_cast(floor(x+.5)); } /*--------------------------------------------------------------------------*/ /* plhead: begin ascii graphics * print opening border, calibrations, etc. */ static void plhead(const PROBELIST& plotlist) { for (PROBELIST::const_iterator i = plotlist.begin(); i != plotlist.end(); ++i) { calibrate(*i); } for (int ii = 0; ii < CONSSCALE; ii++) { /* build strings */ border[ii] = '-'; emptydata[ii] = ' '; } double incr = static_cast(CONSSCALE) / OPT::ydivisions; for (double place = 0.; place < static_cast(CONSSCALE); place += incr) { border[round_to_int(place)] = '+'; emptydata[round_to_int(place)] = '.'; /* tics in emptydata */ } border[CONSSCALE] = '+'; /* fix ends of the strings */ border[CONSSCALE+1] = '\0'; emptydata[CONSSCALE] = emptydata[0] = '|'; emptydata[CONSSCALE+1] = '\0'; plborder(); /* print the border */ } /*--------------------------------------------------------------------------*/ /* point: return coordinate to plot in pixel # */ static int point( double yy, /* raw data */ double lo, double hi, /* limits: both ends of the plot */ int scale, /* length of scale in pixels */ int offset, /* pixel offset of start of plot area */ int linswp) /* flag: linear scale (else log scale) */ { int place; if (linswp) { place = round_to_int( scale*(yy-lo)/(hi-lo)); }else{untested(); place = round_to_int( scale*(log(yy/lo))/(log(hi/lo))); } if (place < 0) { place = 0; } if (place > scale) {itested(); place = scale; } return place + offset; } /*--------------------------------------------------------------------------*/ /* plotarg: plot all 2 selected probes at one time, freq, etc. point. */ /*ARGSUSED*/ static void plotarg( double xx, /* values */ double yy, double zz, double , /* lower limits */ double ylo, double zlo, double , /* upper limits */ double yhi, double zhi) { char adata[MAXWIDTH+1]; /* actual data. copy emptydata, insert */ char *xxs; /* string representation of xx */ memcpy(adata, emptydata, MAXWIDTH); /* copy prototype */ xxs = ftos( xx, 11, 5, IO::formaat ); if (zz != NOT_VALID) { adata[point(zz,zlo,zhi,CONSSCALE,0,1)] = '+';/* zap data into string */ } adata[point(yy,ylo,yhi,CONSSCALE,0,1)] = '*'; IO::plotout.form( "%-8.8s%s", xxs, adata ); IO::plotout << '\n'; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/s__.h�������������������������������������������������������������������������������������������0000664�0000000�0000000�00000007150�11454012162�0012555�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: s__.h,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * base class for simulation methods */ //testing=script,complete 2006.07.14 #ifndef S___H #define S___H #include "u_opt.h" #include "c_comand.h" /*--------------------------------------------------------------------------*/ class CARD; class CARD_LIST; class CS; class PROBELIST; class COMPONENT; class WAVE; /*--------------------------------------------------------------------------*/ class INTERFACE SIM : public CMD { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ protected: enum TRACE { // how much diagnostics to show tNONE = 0, /* no extended diagnostics */ tUNDER = 1, /* show underlying analysis, important pts only */ tALLTIME = 2, /* show every time step, including hidden */ tREJECTED = 3, /* show rejected time steps */ tITERATION = 4, /* show every iteration, including nonconverged */ tVERBOSE = 5 /* show extended diagnostics */ }; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ CARD_LIST* _scope; OMSTREAM _out; /* places to send the results */ public: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ private: const std::string long_label()const {unreachable(); return "";} private: virtual void setup(CS&) = 0; virtual void sweep() = 0; virtual void finish() {} virtual bool is_step_rejected()const {return false;} explicit SIM(const SIM&):CMD(),_scope(NULL) {unreachable(); incomplete();} protected: explicit SIM(): CMD(),_scope(NULL) {} public: ~SIM(); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ protected: void command_base(CS&); /* s__init.cc */ void reset_timers(); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ protected: const PROBELIST& alarmlist()const; /* s__out.cc */ const PROBELIST& plotlist()const; const PROBELIST& printlist()const; const PROBELIST& storelist()const; virtual void outdata(double); virtual void head(double,double,const std::string&); virtual void print_results(double); virtual void alarm(); virtual void store_results(double); public: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ protected: /* s__solve.cc */ bool solve(OPT::ITL,TRACE); bool solve_with_homotopy(OPT::ITL,TRACE); protected: void finish_building_evalq(); void advance_time(); void set_flags(); void clear_arrays(); void evaluate_models(); void set_damp(); void load_matrix(); void solve_equations(); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/s__init.cc��������������������������������������������������������������������������������������0000664�0000000�0000000�00000005470�11454012162�0013602�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: s__init.cc,v 26.135 2009/12/02 09:26:53 al Exp $ * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * initialization (allocation, node mapping, etc) */ //testing=obsolete #include "u_status.h" #include "u_sim_data.h" #include "s__.h" /*--------------------------------------------------------------------------*/ void SIM::command_base(CS& cmd) { reset_timers(); _sim->reset_iteration_counter(_sim->_mode); _sim->reset_iteration_counter(iPRINTSTEP); _sim->init(); _sim->alloc_vectors(); _sim->_aa.reallocate(); _sim->_aa.dezero(OPT::gmin); _sim->_aa.set_min_pivot(OPT::pivtol); _sim->_lu.reallocate(); _sim->_lu.dezero(OPT::gmin); _sim->_lu.set_min_pivot(OPT::pivtol); assert(_sim->_nstat); try { setup(cmd); ::status.set_up.stop(); switch (ENV::run_mode) { case rPRE_MAIN: unreachable(); break; case rBATCH: itested(); case rINTERACTIVE: itested(); case rSCRIPT: sweep(); break; case rPRESET: /*nothing*/ break; } }catch (Exception& e) {untested(); error(bDANGER, e.message() + '\n'); _sim->count_iterations(iTOTAL); _sim->_lu.unallocate(); _sim->_aa.unallocate(); } _sim->unalloc_vectors(); finish(); ::status.total.stop(); } /*--------------------------------------------------------------------------*/ SIM::~SIM() { _sim->uninit(); } /*--------------------------------------------------------------------------*/ void SIM::reset_timers() { ::status.advance.reset(); ::status.queue.reset(); ::status.evaluate.reset(); ::status.load.reset(); ::status.lud.reset(); ::status.back.reset(); ::status.review.reset(); ::status.accept.reset(); ::status.output.reset(); ::status.aux1.reset(); ::status.aux2.reset(); ::status.aux3.reset(); ::status.set_up.reset().start(); ::status.total.reset().start(); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/s__out.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000010310�11454012162�0013433�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: s__out.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * tr,dc analysis output functions (and some ac) */ //testing=obsolete,script 2005.09.17 #include "u_sim_data.h" #include "u_status.h" #include "m_wave.h" #include "u_prblst.h" #include "declare.h" /* plottr, plopen */ #include "s__.h" /*--------------------------------------------------------------------------*/ /* SIM::____list: access probe lists */ const PROBELIST& SIM::alarmlist()const { return PROBE_LISTS::alarm[_sim->_mode]; } const PROBELIST& SIM::plotlist()const { return PROBE_LISTS::plot[_sim->_mode]; } const PROBELIST& SIM::printlist()const { return PROBE_LISTS::print[_sim->_mode]; } const PROBELIST& SIM::storelist()const { return PROBE_LISTS::store[_sim->_mode]; } /*--------------------------------------------------------------------------*/ /* SIM::out: output the data, "keep" for ac reference */ void SIM::outdata(double x) { ::status.output.start(); plottr(x, plotlist()); print_results(x); alarm(); store_results(x); _sim->reset_iteration_counter(iPRINTSTEP); ::status.hidden_steps = 0; ::status.output.stop(); } /*--------------------------------------------------------------------------*/ /* SIM::head: print column headings and draw plot borders */ void SIM::head(double start, double stop, const std::string& col1) { if (_sim->_waves) { delete [] _sim->_waves; }else{ } _sim->_waves = new WAVE [storelist().size()]; if (!plopen(start, stop, plotlist())) { // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ int width = std::min(OPT::numdgt+5, BIGBUFLEN-10); char format[20]; //sprintf(format, "%%c%%-%u.%us", width, width); sprintf(format, "%%c%%-%us", width); _out.form(format, '#', col1.c_str()); for (PROBELIST::const_iterator p=printlist().begin(); p!=printlist().end(); ++p) { _out.form(format, ' ', p->label().c_str()); } _out << '\n'; }else{ } } /*--------------------------------------------------------------------------*/ /* SIM::print_results: print the list of results (text form) to _out * The argument is the first column (independent variable, aka "x") */ void SIM::print_results(double x) { if (!IO::plotout.any()) { _out.setfloatwidth(OPT::numdgt, OPT::numdgt+6); assert(x != NOT_VALID); _out << x; for (PROBELIST::const_iterator p=printlist().begin(); p!=printlist().end(); ++p) { _out << p->value(); } _out << '\n'; }else{ } } /*--------------------------------------------------------------------------*/ /* SIM::alarm: print a message when a probe is out of range */ void SIM::alarm(void) { _out.setfloatwidth(OPT::numdgt, OPT::numdgt+6); for (PROBELIST::const_iterator p=alarmlist().begin(); p!=alarmlist().end(); ++p) { if (!p->in_range()) { _out << p->label() << '=' << p->value() << '\n'; }else{ } } } /*--------------------------------------------------------------------------*/ /* SIM::store: store data in preparation for post processing */ void SIM::store_results(double x) { int ii = 0; for (PROBELIST::const_iterator p=storelist().begin(); p!=storelist().end(); ++p) { _sim->_waves[ii++].push(x, p->value()); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/s__solve.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000020720�11454012162�0013762�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: s__solve.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * solve one step of a transient or dc analysis */ //testing=script 2006.07.14 #include "e_cardlist.h" #include "u_status.h" #include "e_node.h" #include "s__.h" /*--------------------------------------------------------------------------*/ // bool SIM::solve(int,int); // void SIM::finish_building_evalq(); // void SIM::advance_time(); // void SIM::set_flags(); // void SIM::clear_arrays(); // void SIM::evaluate_models(); // void SIM::set_damp(); // void SIM::load_matrix(); // void SIM::solve_equations(); /*--------------------------------------------------------------------------*/ static bool converged = false; /*--------------------------------------------------------------------------*/ bool SIM::solve(OPT::ITL itl, TRACE trace) { converged = false; int convergedcount = 0; _sim->reset_iteration_counter(iSTEP); advance_time(); _sim->_damp = OPT::dampmax; do{ if (trace >= tITERATION) { print_results(static_cast(-_sim->iteration_number())); } set_flags(); clear_arrays(); finish_building_evalq(); _sim->count_iterations(iPRINTSTEP); _sim->count_iterations(iSTEP); _sim->count_iterations(_sim->_mode); _sim->count_iterations(iTOTAL); evaluate_models(); if (converged) { if (_sim->_limiting) { error(bDEBUG, "converged beyond limit, resetting limit\n"); _sim->set_limit(); convergedcount = 0; }else{ ++convergedcount; } }else{ convergedcount = 0; } if (convergedcount <= OPT::itermin) { converged = false; } if (!converged || !OPT::fbbypass || _sim->_damp < .99) { set_damp(); load_matrix(); solve_equations(); } }while (!converged && !_sim->exceeds_iteration_limit(itl)); return converged; } /*--------------------------------------------------------------------------*/ bool SIM::solve_with_homotopy(OPT::ITL itl, TRACE trace) { solve(itl, trace); trace2("plain", ::status.iter[iSTEP], OPT::gmin); if (!converged && OPT::itl[OPT::SSTEP] > 0) { int save_itermin = OPT::itermin; OPT::itermin = 0; double save_gmin = OPT::gmin; OPT::gmin = 1; while (_sim->_iter[iPRINTSTEP] < OPT::itl[OPT::SSTEP] && OPT::gmin > save_gmin) { //CARD_LIST::card_list.precalc(); _sim->set_inc_mode_no(); solve(itl, trace); if (!converged) { trace2("fail", _sim->_iter[iSTEP], OPT::gmin); OPT::gmin *= 3.5; }else{ trace2("success", _sim->_iter[iSTEP], OPT::gmin); OPT::gmin /= 4; } } OPT::itermin = save_itermin; OPT::gmin = save_gmin; //CARD_LIST::card_list.precalc(); solve(itl, trace); if (!converged) { trace2("final fail", _sim->_iter[iSTEP], OPT::gmin); }else{ trace2("final success", _sim->_iter[iSTEP], OPT::gmin); } }else{ } return converged; } /*--------------------------------------------------------------------------*/ /* finish_building_evalq * This function scans the circuit to queue for evaluation anything * that is relevant that the devices missed themselves. * For now, it scans the whole circuit, but this will change. * This is slow, but the result is still faster than not having a queue. * The plan is .. every node knows whether it needs eval or not, and * only those nodes needing eval will be scanned. * Its purpose is to catch nodes that wake up after being dormant */ void SIM::finish_building_evalq(void) { ::status.queue.start(); CARD_LIST::card_list.tr_queue_eval(); ::status.queue.stop(); } /*--------------------------------------------------------------------------*/ void SIM::advance_time(void) { ::status.advance.start(); static double last_iter_time; if (_sim->_time0 > 0) { if (_sim->_time0 > last_iter_time) { /* moving forward */ notstd::copy_n(_sim->_v0, _sim->_total_nodes+1, _sim->_vt1); CARD_LIST::card_list.tr_advance(); }else{ /* moving backward */ /* don't save voltages. They're wrong! */ /* instead, restore a clean start for iteration */ notstd::copy_n(_sim->_vt1, _sim->_total_nodes+1, _sim->_v0); CARD_LIST::card_list.tr_regress(); } }else{ CARD_LIST::card_list.dc_advance(); } last_iter_time = _sim->_time0; ::status.advance.stop(); } /* last_iter_time is initially 0 by C definition. * On subsequent runs it will start with an arbitrary positive value. * _sim->_time0 starts at either 0 or the ending time of the last run. * In either case, (time0 > last_iter_time) is false on the first step. * This correctly results in "don't save voltages..." */ /*--------------------------------------------------------------------------*/ void SIM::set_flags() { _sim->_limiting = false; _sim->_fulldamp = false; if (OPT::incmode == false) { _sim->set_inc_mode_no(); }else if (_sim->inc_mode_is_bad()) { _sim->set_inc_mode_no(); }else if (_sim->is_iteration_number(OPT::itl[OPT::TRLOW])) { _sim->set_inc_mode_no(); }else if (_sim->is_iteration_number(0)) { // leave it as is }else{ _sim->set_inc_mode_yes(); } _sim->_bypass_ok = (is_step_rejected() || _sim->_damp < OPT::dampmax*OPT::dampmax) ? false : bool(OPT::bypass); } /*--------------------------------------------------------------------------*/ void SIM::clear_arrays(void) { if (!_sim->is_inc_mode()) { /* Clear working array */ _sim->_aa.zero(); _sim->_aa.dezero(OPT::gmin); /* gmin fudge */ std::fill_n(_sim->_i, _sim->_aa.size()+1, 0); } _sim->_loadq.clear(); } /*--------------------------------------------------------------------------*/ void SIM::evaluate_models() { ::status.evaluate.start(); if (OPT::bypass) { converged = true; swap(_sim->_evalq, _sim->_evalq_uc); while (!_sim->_evalq->empty()) { converged &= _sim->_evalq->front()->do_tr(); _sim->_evalq->pop_front(); } }else{ _sim->_evalq_uc->clear(); converged = CARD_LIST::card_list.do_tr(); } while (!_sim->_late_evalq.empty()) { //BUG// encapsulation violation converged &= _sim->_late_evalq.front()->do_tr_last(); _sim->_late_evalq.pop_front(); } ::status.evaluate.stop(); } /*--------------------------------------------------------------------------*/ void SIM::set_damp() { if (_sim->is_second_iteration() && !converged && OPT::dampstrategy&dsINIT) { _sim->_damp = OPT::dampmin; }else if (_sim->is_first_iteration() || converged) { _sim->_damp = OPT::dampmax; }else if (_sim->_fulldamp) { _sim->_damp = OPT::dampmin; }else{ _sim->_damp = OPT::dampmax; } trace1("", _sim->_damp); } /*--------------------------------------------------------------------------*/ void SIM::load_matrix() { ::status.load.start(); if (OPT::traceload && _sim->is_inc_mode()) { while (!_sim->_loadq.empty()) { _sim->_loadq.back()->tr_load(); _sim->_loadq.pop_back(); } }else{ _sim->_loadq.clear(); CARD_LIST::card_list.tr_load(); } ::status.load.stop(); } /*--------------------------------------------------------------------------*/ void SIM::solve_equations() { ::status.lud.start(); _sim->_lu.lu_decomp(_sim->_aa, bool(OPT::lubypass && _sim->is_inc_mode())); ::status.lud.stop(); ::status.back.start(); _sim->_lu.fbsub(_sim->_v0, _sim->_i, _sim->_v0); ::status.back.stop(); if (_sim->_nstat) { // mixed mode for (int ii = _sim->_lu.size(); ii >= 1; --ii) { _sim->_nstat[ii].set_a_iter(); } }else{ // pure analog untested(); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ������������������������������������������������src/s_ac.cc�����������������������������������������������������������������������������������������0000664�0000000�0000000�00000020351�11454012162�0013056�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: s_ac.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * ac analysis top */ //testing=script 2008.08.06 #include "u_sim_data.h" #include "u_status.h" #include "u_parameter.h" #include "u_prblst.h" #include "s__.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class AC : public SIM { public: void do_it(CS&, CARD_LIST*); explicit AC(): SIM(), _start(), _stop(), _step_in(), _step(0.), _linswp(false), _prevopppoint(false), _stepmode(ONE_PT) {} ~AC() {} private: explicit AC(const AC&):SIM() {unreachable(); incomplete();} void sweep(); void first(); bool next(); void solve(); void clear(); void setup(CS&); private: PARAMETER _start; // sweep start frequency PARAMETER _stop; // sweep stop frequency PARAMETER _step_in; // step size, as input double _step; // printed step size bool _linswp; // flag: use linear sweep (vs log sweep) bool _prevopppoint; // flag: use previous op point enum {ONE_PT, LIN_STEP, LIN_PTS, TIMES, OCTAVE, DECADE} _stepmode; }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void AC::do_it(CS& Cmd, CARD_LIST* Scope) { _scope = Scope; _sim->set_command_ac(); reset_timers(); ::status.ac.reset().start(); _sim->init(); _sim->alloc_vectors(); _sim->_acx.reallocate(); _sim->_acx.set_min_pivot(OPT::pivtol); setup(Cmd); ::status.set_up.stop(); switch (ENV::run_mode) { case rPRE_MAIN: unreachable(); break; case rBATCH: itested(); case rINTERACTIVE: itested(); case rSCRIPT: sweep(); break; case rPRESET: /*nothing*/ break; } _sim->_acx.unallocate(); _sim->unalloc_vectors(); ::status.ac.stop(); ::status.total.stop(); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ static int needslinfix; // flag: lin option needs patch later (spice compat) /*--------------------------------------------------------------------------*/ void AC::setup(CS& Cmd) { _out = IO::mstdout; _out.reset(); //BUG// don't know why this is needed //temp_c = OPT::temp_c; // Don't set temperature. Keep whatever was there before, // from "op" or whatever. bool ploton = IO::plotset && plotlist().size() > 0; ONE_OF || (Get(Cmd, "*", &_step_in) && (_stepmode = TIMES)) || (Get(Cmd, "+", &_step_in) && (_stepmode = LIN_STEP)) || (Get(Cmd, "by", &_step_in) && (_stepmode = LIN_STEP)) || (Get(Cmd, "step", &_step_in) && (_stepmode = LIN_STEP)) || (Get(Cmd, "d{ecade}", &_step_in) && (_stepmode = DECADE)) || (Get(Cmd, "ti{mes}", &_step_in) && (_stepmode = TIMES)) || (Get(Cmd, "lin", &_step_in) && (_stepmode = LIN_PTS)) || (Get(Cmd, "o{ctave}", &_step_in) && (_stepmode = OCTAVE)); if (Cmd.match1("'\"({") || Cmd.is_float()) { Cmd >> _start; if (Cmd.match1("'\"({") || Cmd.is_float()) { Cmd >> _stop; }else{ _stop = _start; } if (Cmd.match1("'\"({") || Cmd.is_float()) { _stepmode = LIN_STEP; Cmd >> _step_in; }else{ } } unsigned here = Cmd.cursor(); do{ ONE_OF || (Get(Cmd, "*", &_step_in) && (_stepmode = TIMES)) || (Get(Cmd, "+", &_step_in) && (_stepmode = LIN_STEP)) || (Get(Cmd, "by", &_step_in) && (_stepmode = LIN_STEP)) || (Get(Cmd, "step", &_step_in) && (_stepmode = LIN_STEP)) || (Get(Cmd, "d{ecade}", &_step_in) && (_stepmode = DECADE)) || (Get(Cmd, "ti{mes}", &_step_in) && (_stepmode = TIMES)) || (Get(Cmd, "lin", &_step_in) && (_stepmode = LIN_PTS)) || (Get(Cmd, "o{ctave}", &_step_in) && (_stepmode = OCTAVE)) || Get(Cmd, "dt{emp}", &_sim->_temp_c, mOFFSET, OPT::temp_c) || Get(Cmd, "pl{ot}", &ploton) || Get(Cmd, "pr{evoppoint}",&_prevopppoint) || Get(Cmd, "sta{rt}", &_start) || Get(Cmd, "sto{p}", &_stop) || Get(Cmd, "te{mperature}",&_sim->_temp_c) || outset(Cmd,&_out) ; }while (Cmd.more() && !Cmd.stuck(&here)); Cmd.check(bWARNING, "what's this??"); _start.e_val(0., _scope); _stop.e_val(0., _scope); _step_in.e_val(0., _scope); _step = _step_in; switch (_stepmode) { case ONE_PT: case LIN_STEP: needslinfix = false; _linswp = true; break; case LIN_PTS:untested(); if (_step <= 2.) {untested();// need to fix step, later _step = 2.; // do it at the end of setup }else{untested(); // a kluge, but this is a patch } needslinfix = true; // and I am too lazy to do it _linswp = true; // right. break; case TIMES:untested(); if (_step == 0. && _start != 0.) {untested(); _step = _stop / _start; }else{untested(); } needslinfix = false; _linswp = false; break; case OCTAVE: if (_step == 0.) {untested(); _step = 1.; }else{ } _step = pow(2.00000001, 1./_step); needslinfix = false; _linswp = false; break; case DECADE: if (_step == 0.) { _step = 1.; }else{ } _step = pow(10., 1./_step); needslinfix = false; _linswp = false; break; }; if (needslinfix) {untested(); // LIN option is # of points. assert(_step >= 2); // Must compute step after _step=(_stop-_start)/(_step-1.); // reading start and stop, needslinfix = false; // but step must be read first }else{ // for Spice compatibility } if (_step==0.) { _step = _stop - _start; _linswp = true; }else{ } IO::plotout = (ploton) ? IO::mstdout : OMSTREAM(); initio(_out); } /*--------------------------------------------------------------------------*/ void AC::solve() { _sim->_acx.zero(); std::fill_n(_sim->_ac, _sim->_total_nodes+1, 0.); ::status.load.start(); _sim->count_iterations(iTOTAL); CARD_LIST::card_list.do_ac(); CARD_LIST::card_list.ac_load(); ::status.load.stop(); ::status.lud.start(); _sim->_acx.lu_decomp(); ::status.lud.stop(); ::status.back.start(); _sim->_acx.fbsub(_sim->_ac); ::status.back.stop(); } /*--------------------------------------------------------------------------*/ void AC::sweep() { head(_start, _stop, "Freq"); first(); CARD_LIST::card_list.ac_begin(); do { _sim->_jomega = COMPLEX(0., _sim->_freq * M_TWO_PI); solve(); outdata(_sim->_freq); } while (next()); } /*--------------------------------------------------------------------------*/ void AC::first() { _sim->_freq = _start; } /*--------------------------------------------------------------------------*/ bool AC::next() { double realstop = (_linswp) ? _stop - _step/100. : _stop / pow(_step,.01); if (!in_order(double(_start), _sim->_freq, realstop)) { return false; }else{ } _sim->_freq = (_linswp) ? _sim->_freq + _step : _sim->_freq * _step; if (in_order(_sim->_freq, double(_start), double(_stop))) { return false; }else{ return true; } } /*--------------------------------------------------------------------------*/ static AC p1; static DISPATCHER::INSTALL d1(&command_dispatcher, "ac", &p1); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/s_dc.cc�����������������������������������������������������������������������������������������0000664�0000000�0000000�00000032712�11454012162�0013065�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: s_dc.cc,v 26.132 2009/11/24 04:26:37 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * dc analysis top */ //testing=script,complete 2006.07.14 #include "u_status.h" #include "u_prblst.h" #include "u_cardst.h" #include "e_elemnt.h" #include "s__.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class DCOP : public SIM { public: void finish(); protected: void fix_args(int); void options(CS&, int); private: void sweep(); void sweep_recursive(int); void first(int); bool next(int); explicit DCOP(const DCOP&): SIM() {unreachable(); incomplete();} protected: explicit DCOP(); ~DCOP() {} protected: enum {DCNEST = 4}; int _n_sweeps; PARAMETER _start[DCNEST]; PARAMETER _stop[DCNEST]; PARAMETER _step_in[DCNEST]; double _step[DCNEST]; bool _linswp[DCNEST]; double* (_sweepval[DCNEST]); /* pointer to thing to sweep, dc command */ ELEMENT* (_zap[DCNEST]); /* to branch to zap, for re-expand */ CARDSTASH _stash[DCNEST]; /* store std values of elements being swept */ bool _loop[DCNEST]; /* flag: do it again backwards */ bool _reverse_in[DCNEST]; /* flag: sweep backwards, input */ bool _reverse[DCNEST]; /* flag: sweep backwards, working */ bool _cont; /* flag: continue from previous run */ TRACE _trace; /* enum: show extended diagnostics */ enum {ONE_PT, LIN_STEP, LIN_PTS, TIMES, OCTAVE, DECADE} _stepmode[DCNEST]; static double temp_c_in; /* ambient temperature, input and sweep variable */ }; /*--------------------------------------------------------------------------*/ double DCOP::temp_c_in = 0.; /*--------------------------------------------------------------------------*/ class DC : public DCOP { public: explicit DC(): DCOP() {} ~DC() {} void do_it(CS&, CARD_LIST*); private: void setup(CS&); explicit DC(const DC&): DCOP() {unreachable(); incomplete();} }; /*--------------------------------------------------------------------------*/ class OP : public DCOP { public: explicit OP(): DCOP() {} ~OP() {} void do_it(CS&, CARD_LIST*); private: void setup(CS&); explicit OP(const OP&): DCOP() {unreachable(); incomplete();} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ void DC::do_it(CS& Cmd, CARD_LIST* Scope) { _scope = Scope; _sim->_time0 = 0.; _sim->set_command_dc(); _sim->_phase = p_INIT_DC; ::status.dc.reset().start(); _sim->_temp_c = temp_c_in; command_base(Cmd); ::status.dc.stop(); } /*--------------------------------------------------------------------------*/ void OP::do_it(CS& Cmd, CARD_LIST* Scope) { _scope = Scope; _sim->_time0 = 0.; _sim->set_command_op(); _sim->_phase = p_INIT_DC; ::status.op.reset().start(); _sim->_temp_c = temp_c_in; command_base(Cmd); ::status.op.stop(); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DCOP::DCOP() :SIM(), _n_sweeps(1), _cont(false), _trace(tNONE) { for (int ii = 0; ii < DCNEST; ++ii) { _loop[ii] = false; _reverse_in[ii] = false; _reverse[ii] = false; _step[ii]=0.; _linswp[ii]=true; _sweepval[ii]=&_sim->_genout; _zap[ii]=NULL; _stepmode[ii] = ONE_PT; } //BUG// in SIM. should be initialized there. _sim->_genout=0.; temp_c_in=OPT::temp_c; _out=IO::mstdout; _sim->_uic=false; } /*--------------------------------------------------------------------------*/ void DCOP::finish(void) { for (int ii = 0; ii < _n_sweeps; ++ii) { if (exists(_zap[ii])) { // component _stash[ii].restore(); _zap[ii]->dec_probes(); _zap[ii]->precalc_first(); _zap[ii]->precalc_last(); }else{ } } } /*--------------------------------------------------------------------------*/ void OP::setup(CS& Cmd) { _sim->_temp_c = temp_c_in; _cont = false; _trace = tNONE; _out = IO::mstdout; _out.reset(); //BUG// don't know why this is needed */ bool ploton = IO::plotset && plotlist().size() > 0; _zap[0] = NULL; _sweepval[0] = &temp_c_in; if (Cmd.match1("'\"({") || Cmd.is_float()) { Cmd >> _start[0]; if (Cmd.match1("'\"({") || Cmd.is_float()) { Cmd >> _stop[0]; }else{ _stop[0] = _start[0]; } }else{ } _step[0] = 0.; _sim->_genout = 0.; options(Cmd,0); _n_sweeps = 1; Cmd.check(bWARNING, "what's this?"); _sim->_freq = 0; IO::plotout = (ploton) ? IO::mstdout : OMSTREAM(); initio(_out); _start[0].e_val(OPT::temp_c, _scope); fix_args(0); } /*--------------------------------------------------------------------------*/ void DC::setup(CS& Cmd) { _cont = false; _trace = tNONE; _out = IO::mstdout; _out.reset(); //BUG// don't know why this is needed */ bool ploton = IO::plotset && plotlist().size() > 0; if (Cmd.more()) { for (_n_sweeps = 0; Cmd.more() && _n_sweeps < DCNEST; ++_n_sweeps) { CARD_LIST::fat_iterator ci = findbranch(Cmd, &CARD_LIST::card_list); if (!ci.is_end()) { // sweep a component if (ELEMENT* c = dynamic_cast(*ci)) { _zap[_n_sweeps] = c; }else{untested(); throw Exception("dc/op: can't sweep " + (**ci).long_label() + '\n'); } }else if (Cmd.is_float()) { // sweep the generator _zap[_n_sweeps] = NULL; }else{ // leave as it was .. repeat Cmd with no args } if (Cmd.match1("'\"({") || Cmd.is_float()) { // set up parameters _start[_n_sweeps] = "NA"; _stop[_n_sweeps] = "NA"; Cmd >> _start[_n_sweeps] >> _stop[_n_sweeps]; _step[_n_sweeps] = 0.; }else{ // leave it as it was .. repeat Cmd with no args } _sim->_genout = 0.; temp_c_in = OPT::temp_c; _sim->_temp_c = temp_c_in; options(Cmd,_n_sweeps); } }else{ } Cmd.check(bWARNING, "what's this?"); IO::plotout = (ploton) ? IO::mstdout : OMSTREAM(); initio(_out); assert(_n_sweeps > 0); for (int ii = 0; ii < _n_sweeps; ++ii) { _start[ii].e_val(0., _scope); fix_args(ii); if (exists(_zap[ii])) { // component _stash[ii] = _zap[ii]; // stash the std value _zap[ii]->inc_probes(); // we need to keep track of it _zap[ii]->set_value(_zap[ii]->value(),0); // zap out extensions _zap[ii]->set_constant(false); // so it will be updated _sweepval[ii] = _zap[ii]->set__value(); // point to value to patch }else{ // generator _sweepval[ii] = &_sim->_genout; // point to value to patch } } _sim->_freq = 0; } /*--------------------------------------------------------------------------*/ void DCOP::fix_args(int Nest) { _stop[Nest].e_val(_start[Nest], _scope); _step_in[Nest].e_val(0., _scope); _step[Nest] = _step_in[Nest]; switch (_stepmode[Nest]) { case ONE_PT: case LIN_STEP: _linswp[Nest] = true; break; case LIN_PTS:untested(); if (_step[Nest] <= 2.) {untested(); _step[Nest] = 2.; }else{untested(); } _linswp[Nest] = true; break; case TIMES:untested(); if (_step[Nest] == 0. && _start[Nest] != 0.) {untested(); _step[Nest] = _stop[Nest] / _start[Nest]; }else{untested(); } _linswp[Nest] = false; break; case OCTAVE: if (_step[Nest] == 0.) {untested(); _step[Nest] = 1.; }else{ } _step[Nest] = pow(2.00000001, 1./_step[Nest]); _linswp[Nest] = false; break; case DECADE: if (_step[Nest] == 0.) { _step[Nest] = 1.; }else{ } _step[Nest] = pow(10., 1./_step[Nest]); _linswp[Nest] = false; break; }; if (_step[Nest] == 0.) { // prohibit log sweep from 0 _step[Nest] = _stop[Nest] - _start[Nest]; _linswp[Nest] = true; }else{ } } /*--------------------------------------------------------------------------*/ void DCOP::options(CS& Cmd, int Nest) { _sim->_uic = _loop[Nest] = _reverse_in[Nest] = false; unsigned here = Cmd.cursor(); do{ ONE_OF || (Cmd.match1("'\"({") && ((Cmd >> _step_in[Nest]), (_stepmode[Nest] = LIN_STEP))) || (Cmd.is_float() && ((Cmd >> _step_in[Nest]), (_stepmode[Nest] = LIN_STEP))) || (Get(Cmd, "*", &_step_in[Nest]) && (_stepmode[Nest] = TIMES)) || (Get(Cmd, "+", &_step_in[Nest]) && (_stepmode[Nest] = LIN_STEP)) || (Get(Cmd, "by", &_step_in[Nest]) && (_stepmode[Nest] = LIN_STEP)) || (Get(Cmd, "step", &_step_in[Nest]) && (_stepmode[Nest] = LIN_STEP)) || (Get(Cmd, "d{ecade}", &_step_in[Nest]) && (_stepmode[Nest] = DECADE)) || (Get(Cmd, "ti{mes}", &_step_in[Nest]) && (_stepmode[Nest] = TIMES)) || (Get(Cmd, "lin", &_step_in[Nest]) && (_stepmode[Nest] = LIN_PTS)) || (Get(Cmd, "o{ctave}", &_step_in[Nest]) && (_stepmode[Nest] = OCTAVE)) || Get(Cmd, "c{ontinue}", &_cont) || Get(Cmd, "dt{emp}", &temp_c_in, mOFFSET, OPT::temp_c) || Get(Cmd, "lo{op}", &_loop[Nest]) || Get(Cmd, "re{verse}", &_reverse_in[Nest]) || Get(Cmd, "te{mperature}",&temp_c_in) || (Cmd.umatch("tr{ace} {=}") && (ONE_OF || Set(Cmd, "n{one}", &_trace, tNONE) || Set(Cmd, "o{ff}", &_trace, tNONE) || Set(Cmd, "w{arnings}", &_trace, tUNDER) || Set(Cmd, "i{terations}",&_trace, tITERATION) || Set(Cmd, "v{erbose}", &_trace, tVERBOSE) || Cmd.warn(bWARNING, "need none, off, warnings, iterations, verbose") ) ) || outset(Cmd,&_out) ; }while (Cmd.more() && !Cmd.stuck(&here)); } /*--------------------------------------------------------------------------*/ void DCOP::sweep() { head(_start[0], _stop[0], " "); _sim->_bypass_ok = false; _sim->set_inc_mode_bad(); if (_cont) {untested(); _sim->restore_voltages(); }else{ } _sim->clear_limit(); CARD_LIST::card_list.tr_begin(); sweep_recursive(_n_sweeps); } /*--------------------------------------------------------------------------*/ void DCOP::sweep_recursive(int Nest) { --Nest; assert(Nest >= 0); assert(Nest < DCNEST); OPT::ITL itl = OPT::DCBIAS; first(Nest); do { _sim->_temp_c = temp_c_in; if (Nest == 0) { int converged = solve_with_homotopy(itl,_trace); if (!converged) {itested(); error(bWARNING, "did not converge\n"); }else{ } ::status.accept.start(); _sim->set_limit(); CARD_LIST::card_list.tr_accept(); ::status.accept.stop(); _sim->keep_voltages(); outdata(*_sweepval[Nest]); itl = OPT::DCXFER; }else{ sweep_recursive(Nest); } } while (next(Nest)); } /*--------------------------------------------------------------------------*/ void DCOP::first(int Nest) { assert(Nest >= 0); assert(Nest < DCNEST); assert(_start); assert(_sweepval); assert(_sweepval[Nest]); *_sweepval[Nest] = _start[Nest]; _reverse[Nest] = false; if (_reverse_in[Nest]) {itested(); while (next(Nest)) {itested(); /* nothing */; } _reverse[Nest] = true; next(Nest); }else{ } _sim->_phase = p_INIT_DC; } /*--------------------------------------------------------------------------*/ bool DCOP::next(int Nest) { bool ok = false; if (_linswp[Nest]) { double fudge = _step[Nest] / 10.; if (_step[Nest] == 0.) { ok = false; }else{ if (!_reverse[Nest]) { *(_sweepval[Nest]) += _step[Nest]; fixzero(_sweepval[Nest], _step[Nest]); ok=in_order(_start[Nest]-fudge,*(_sweepval[Nest]),_stop[Nest]+fudge); if (!ok && _loop[Nest]) { _reverse[Nest] = true; }else{ } }else{ } if (_reverse[Nest]) { *(_sweepval[Nest]) -= _step[Nest]; fixzero(_sweepval[Nest], _step[Nest]); ok=in_order(_start[Nest]-fudge,*(_sweepval[Nest]),_stop[Nest]+fudge); }else{ } } }else{ double fudge = pow(_step[Nest], .1); if (_step[Nest] == 1.) {untested(); ok = false; }else{ if (!_reverse[Nest]) { *(_sweepval[Nest]) *= _step[Nest]; ok=in_order(_start[Nest]/fudge,*(_sweepval[Nest]),_stop[Nest]*fudge); if (!ok && _loop[Nest]) {untested(); _reverse[Nest] = true; }else{ } }else{ } if (_reverse[Nest]) {untested(); *(_sweepval[Nest]) /= _step[Nest]; ok=in_order(_start[Nest]/fudge,*(_sweepval[Nest]),_stop[Nest]*fudge); }else{ } } } _sim->_phase = p_DC_SWEEP; return ok; } /*--------------------------------------------------------------------------*/ static DC p2; static OP p4; static DISPATCHER::INSTALL d2(&command_dispatcher, "dc", &p2); static DISPATCHER::INSTALL d4(&command_dispatcher, "op", &p4); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ������������������������������������������������������src/s_fo.cc�����������������������������������������������������������������������������������������0000664�0000000�0000000�00000024702�11454012162�0013103�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: s_fo.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * tran and fourier commands -- top * performs transient analysis, silently, then fft. * outputs results of fft */ //testing=script 2007.11.21 #include "u_sim_data.h" #include "u_status.h" #include "m_phase.h" #include "declare.h" /* plclose, plclear, fft */ #include "u_prblst.h" #include "s_tr.h" /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ class FOURIER : public TRANSIENT { public: void do_it(CS&, CARD_LIST*); explicit FOURIER(): TRANSIENT(), _fstart(0.), _fstop(0.), _fstep(0.), _timesteps(0), _fdata(NULL) { } ~FOURIER() {} private: explicit FOURIER(const FOURIER&): TRANSIENT() {unreachable(); incomplete();} std::string status()const {return "";} void setup(CS&); /* s_fo_set.cc */ void fftallocate(); void fftunallocate(); void foout(); /* s_fo_out.cc */ void fohead(const PROBE&); void foprint(COMPLEX*); void store_results(double); // override virtual private: PARAMETER _fstart; /* user start frequency */ PARAMETER _fstop; /* user stop frequency */ PARAMETER _fstep; /* fft frequecncy step */ int _timesteps; /* number of time steps in tran analysis, incl 0 */ COMPLEX** _fdata; /* storage to allow postprocessing */ }; /*--------------------------------------------------------------------------*/ static int to_pow_of_2(double); static int stepnum(double,double,double); static COMPLEX find_max(COMPLEX*,int,int); static double db(COMPLEX); /*--------------------------------------------------------------------------*/ void FOURIER::do_it(CS& Cmd, CARD_LIST* Scope) { _scope = Scope; _sim->set_command_fourier(); reset_timers(); ::status.four.reset().start(); try { _sim->init(); _sim->alloc_vectors(); _sim->_aa.reallocate(); _sim->_aa.dezero(OPT::gmin); _sim->_aa.set_min_pivot(OPT::pivtol); _sim->_lu.reallocate(); _sim->_lu.dezero(OPT::gmin); _sim->_lu.set_min_pivot(OPT::pivtol); setup(Cmd); fftallocate(); ::status.set_up.stop(); switch (ENV::run_mode) {untested(); case rPRE_MAIN: unreachable(); break; case rBATCH: untested(); case rINTERACTIVE: itested(); case rSCRIPT: sweep(); foout(); break; case rPRESET: untested(); /*nothing*/ break; } }catch (Exception& e) {itested(); error(bDANGER, e.message() + '\n'); } fftunallocate(); _sim->unalloc_vectors(); _sim->_lu.unallocate(); _sim->_aa.unallocate(); ::status.four.stop(); ::status.total.stop(); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* store: stash time domain data in preparation for Fourier Transform */ void FOURIER::store_results(double X) { TRANSIENT::store_results(X); if (step_cause() == scUSER) { int ii = 0; for (PROBELIST::const_iterator p=printlist().begin(); p!=printlist().end(); ++p) { assert(_stepno < _timesteps); _fdata[ii][_stepno] = p->value(); ++ii; } }else{untested(); } } /*--------------------------------------------------------------------------*/ /* foout: print out the results of the transform */ void FOURIER::foout() { plclose(); plclear(); int ii = 0; for (PROBELIST::const_iterator p=printlist().begin(); p!=printlist().end(); ++p) { fohead(*p); fft(_fdata[ii], _timesteps-1, 0); foprint(_fdata[ii]); ++ii; } } /*--------------------------------------------------------------------------*/ /* fo_head: print output header * arg is index into probe array, to select probe name */ void FOURIER::fohead(const PROBE& Prob) { _out.form("# %-10s", Prob.label().c_str()) << "--------- actual --------- -------- relative --------\n" << "#freq " << "value dB phase value dB phase\n"; } /*--------------------------------------------------------------------------*/ /* fo_print: print results of fourier analysis * for all points at single probe */ void FOURIER::foprint(COMPLEX *Data) { int startstep = stepnum(0., _fstep, _fstart); assert(startstep >= 0); int stopstep = stepnum(0., _fstep, _fstop ); assert(stopstep < _timesteps); COMPLEX maxvalue = find_max(Data, std::max(1,startstep), stopstep); if (maxvalue == 0.) {untested(); maxvalue = 1.; }else{ } Data[0] /= 2; for (int ii = startstep; ii <= stopstep; ++ii) { double frequency = _fstep * ii; assert(ii >= 0); assert(ii < _timesteps); COMPLEX unscaled = Data[ii]; COMPLEX scaled = unscaled / maxvalue; unscaled *= 2; _out.form("%s%s%7.2f %8.3f %s%7.2f %8.3f\n", ftos(frequency, 11,5,_out.format()), ftos(std::abs(unscaled),11,5,_out.format()), db(unscaled), phase(unscaled*COMPLEX(0.,1)), ftos(std::abs(scaled), 11,5,_out.format()), db(scaled), phase(scaled) ) ; } } /*--------------------------------------------------------------------------*/ /* stepnum: return step number given its frequency or time */ static int stepnum(double Start, double Step, double Here) { return int((Here-Start)/Step + .5); } /*--------------------------------------------------------------------------*/ /* find_max: find the max magnitude in a COMPLEX array */ static COMPLEX find_max(COMPLEX *Data, int Start, int Stop) { COMPLEX maxvalue = 0.; for (int ii = Start; ii <= Stop; ++ii) { if (std::abs(Data[ii]) > std::abs(maxvalue)) { maxvalue = Data[ii]; }else{ } } return maxvalue; } /*--------------------------------------------------------------------------*/ static double db(COMPLEX Value) { return 20. * log10(std::max(std::abs(Value),VOLTMIN)); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* fo_setup: fourier analysis: parse command string and set options * (options set by call to TRANSIENT::options) */ void FOURIER::setup(CS& Cmd) { _cont = true; if (Cmd.match1("'\"({") || Cmd.is_pfloat()) { PARAMETER arg1, arg2, arg3; Cmd >> arg1; if (Cmd.match1("'\"({") || Cmd.is_float()) { Cmd >> arg2; }else{ } if (Cmd.match1("'\"({") || Cmd.is_float()) { Cmd >> arg3; }else{ } if (arg3.has_hard_value()) { /* 3 args: all */ assert(arg2.has_hard_value()); assert(arg1.has_hard_value()); _fstart = arg1; _fstop = arg2; _fstep = arg3; }else if (arg2.has_hard_value()) {untested(); /* 2 args: start = 0 */ assert(arg1.has_hard_value()); arg1.e_val(0.,_scope); arg2.e_val(0.,_scope); if (arg1 >= arg2) {untested(); /* 2 args: stop, step */ _fstart = "NA"; /* (stop > step) */ _fstop = arg1; _fstep = arg2; }else{untested(); /* arg1 < arg2 */ /* 2 args: step, stop */ _fstart = "NA"; _fstop = arg2; _fstep = arg1; } }else{ assert(arg1.has_hard_value()); arg1.e_val(0.,_scope); if (arg1 == 0.) {untested(); /* 1 arg: start */ _fstart = 0.; /* _fstop unchanged */ /* _fstep unchanged */ }else{untested(); /* 1 arg: step */ _fstart = "NA"; _fstop = "NA"; _fstep = arg1; } } }else{itested(); /* else (no args) : no change */ } options(Cmd); _fstart.e_val(0., _scope); _fstep.e_val(0., _scope); _fstop.e_val(OPT::harmonics * _fstep, _scope); if (_fstep == 0.) {itested(); throw Exception("frequency step = 0"); }else{ } if (_fstop == 0.) {untested(); _fstop = OPT::harmonics * _fstep; }else{ } _timesteps = to_pow_of_2(_fstop*2 / _fstep) + 1; if (_cold || _sim->_last_time <= 0.) { _cont = false; _tstart = 0.; }else{ _cont = true; _tstart = _sim->_last_time; } _tstop = _tstart + 1. / _fstep; _tstep = 1. / _fstep / (_timesteps-1); time1 = _sim->_time0 = _tstart; _sim->_freq = _fstep; _dtmax = std::min(double(_dtmax_in), _tstep / double(_skip_in)); if (_dtmin_in.has_hard_value()) { _sim->_dtmin = _dtmin_in; }else if (_dtratio_in.has_hard_value()) { _sim->_dtmin = _dtmax / _dtratio_in; }else{ // use smaller of soft values _sim->_dtmin = std::min(double(_dtmin_in), _dtmax/_dtratio_in); } } /*--------------------------------------------------------------------------*/ /* allocate: allocate space for fft */ void FOURIER::fftallocate() { int probes = printlist().size(); _fdata = new COMPLEX*[probes]; for (int ii = 0; ii < probes; ++ii) { _fdata[ii] = new COMPLEX[_timesteps+100]; } } /*--------------------------------------------------------------------------*/ /* unallocate: unallocate space for fft */ void FOURIER::fftunallocate() { if (_fdata) { for (int ii = 0; ii < printlist().size(); ++ii) { delete [] _fdata[ii]; } delete [] _fdata; _fdata = NULL; }else{itested(); } } /*--------------------------------------------------------------------------*/ /* to_pow_of_2: round up to nearest power of 2 * example: z=92 returns 128 */ static int to_pow_of_2(double Z) { int x = static_cast(floor(Z)); int y; for (y = 1; x > 0; x >>= 1) { y <<= 1; } return y; } /*--------------------------------------------------------------------------*/ static FOURIER p3; DISPATCHER::INSTALL d3(&command_dispatcher, "fourier", &p3); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������src/s_tr.cc�����������������������������������������������������������������������������������������0000664�0000000�0000000�00000004204�11454012162�0013117�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: s_tr.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * tran and fourier commands -- top */ //testing=script,complete 2007.11.22 #include "u_sim_data.h" #include "u_status.h" #include "s_tr.h" static TRANSIENT p5; DISPATCHER::INSTALL d5(&command_dispatcher, "transient", &p5); DISPATCHER::INSTALL d6(&status_dispatcher, "transient", &p5); /*--------------------------------------------------------------------------*/ int TRANSIENT::steps_accepted_; int TRANSIENT::steps_rejected_; int TRANSIENT::steps_total_; /*--------------------------------------------------------------------------*/ void TRANSIENT::do_it(CS& Cmd, CARD_LIST* Scope) { _scope = Scope; _sim->set_command_tran(); ::status.tran.reset().start(); command_base(Cmd); ::status.tran.stop(); } /*--------------------------------------------------------------------------*/ std::string TRANSIENT::status()const { return "transient timesteps: accepted=" + to_string(steps_accepted()) + ", rejected=" + to_string(steps_rejected()) + ", total=" + to_string(steps_total()) + "\n"; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/s_tr.h������������������������������������������������������������������������������������������0000664�0000000�0000000�00000011340�11454012162�0012760�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: s_tr.h,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * Transient analysis */ //testing=script,complete 2006.07.14 #ifndef S_TR_H #define S_TR_H #include "u_parameter.h" #include "s__.h" /*--------------------------------------------------------------------------*/ class TRANSIENT : public SIM { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ protected: enum STEP_CAUSE { scUSER = 1, /* user requested */ scEVENTQ = 2, /* an "event" from the queue */ scSKIP = 3, /* effect of "skip" parameter */ scITER_R = 4, /* iter count exceeds itl4 (reducing) */ scITER_A = 5, /* iter count exceeds itl3 (holding) */ scTE = 6, /* truncation error, or device stuff */ scAMBEVENT = 7, /* ambiguous event */ scADT = 8, /* by iter count limited by max(rdt, 2*adt) */ scINITIAL = 9, /* initial guess */ scREJECT = 10, /* rejected previous time step */ scZERO = 20, /* fixed zero time step */ scSMALL = 30, /* time step too small */ scNO_ADVANCE= 100 /* after all that it still didn't advance */ }; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ public: explicit TRANSIENT(): SIM(), _skip_in(1), _dtmax(0.), _cold(false), _cont(false), _trace(tNONE), _time_by_iteration_count(0.), _time_by_user_request(0.), _time_by_error_estimate(0.), _time_by_ambiguous_event(0.), _converged(false), _accepted(false) { } ~TRANSIENT() {} public: void do_it(CS&, CARD_LIST* scope); std::string status()const; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ private: // s_tr_rev.cc bool review(); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ private: // s_tr_set.cc void setup(CS&); protected: void options(CS&); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ protected: // s_tr_swp.cc void sweep(); private: void set_step_cause(STEP_CAUSE); public: int step_cause()const; void first(); bool next(); void accept(); void reject(); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ private: bool is_step_rejected()const {return (step_cause() > scREJECT);} explicit TRANSIENT(const TRANSIENT&): SIM(),_skip_in(1) {unreachable(); incomplete();} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ protected: PARAMETER _tstart; // sweep start time PARAMETER _tstop; // sweep stop time PARAMETER _tstep; // printed step size PARAMETER _dtratio_in;// ratio of max/min dt PARAMETER _dtmin_in; // min internal step size PARAMETER _dtmax_in; // max internal step size (user) PARAMETER _skip_in; // fixed step size: internal steps per external double time1; /* time at previous time step */ double _dtmax; // max internal step size (step / _skip) bool _cold; // flag: start time=0, all voltages=0 bool _cont; // flag: continue from previous run int _stepno; // count of visible (saved) steps private: TRACE _trace; // enum: show extended diagnostics double _time_by_iteration_count; double _time_by_user_request; double _time_by_error_estimate; double _time_by_ambiguous_event; bool _converged; bool _accepted; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ private: static int steps_accepted_; static int steps_rejected_; static int steps_total_; public: static int steps_accepted() {return steps_accepted_;} static int steps_rejected() {return steps_rejected_;} static int steps_total() {return steps_total_;} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/s_tr_set.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000015637�11454012162�0014006�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: s_tr_set.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * set up transient and fourier analysis */ //testing=script 2007.11.21 #include "u_sim_data.h" #include "u_prblst.h" #include "ap.h" #include "s_tr.h" /*--------------------------------------------------------------------------*/ // void TRANSIENT::setup(CS&); // void TRANSIENT::options(CS&); /*--------------------------------------------------------------------------*/ /* tr_setup: transient analysis: parse command string and set options * (options set by call to tr_options) */ void TRANSIENT::setup(CS& Cmd) { _tstart.e_val(NOT_INPUT, _scope); _tstop.e_val(NOT_INPUT, _scope); _tstep.e_val(NOT_INPUT, _scope); _cont = true; if (Cmd.match1("'\"({") || Cmd.is_pfloat()) { PARAMETER arg1, arg2, arg3; Cmd >> arg1; if (Cmd.match1("'\"({") || Cmd.is_float()) { Cmd >> arg2; }else{itested(); } if (Cmd.match1("'\"({") || Cmd.is_float()) { Cmd >> arg3; }else{ } if (arg3.has_hard_value()) { /* 3 args: all */ assert(arg2.has_hard_value()); assert(arg1.has_hard_value()); arg1.e_val(0.,_scope); arg3.e_val(0.,_scope); if (arg3 == 0.) { /* spice (illogical) order */ _tstart = arg3; /* _tstep _tstop _tstart */ _tstop = arg2; _tstep = arg1; }else if (arg1 == 0.) { /* eca (logical) order: */ _tstart = arg1; /* _tstart _tstop _tstep */ _tstop = arg2; _tstep = arg3; }else if (arg1 > arg3) {untested(); /* eca (logical) order: */ _tstart = arg1; /* _tstart _tstop _tstep */ _tstop = arg2; _tstep = arg3; }else{untested(); /* spice (illogical) order */ _tstart = arg3; /* _tstep _tstop _tstart */ _tstop = arg2; _tstep = arg1; } }else if (arg2.has_hard_value()) { /* 2 args */ assert(arg1.has_hard_value()); arg1.e_val(0.,_scope); arg2.e_val(0.,_scope); if (arg1 == 0.) {untested(); /* 2 args: _tstart, _tstop */ _tstart = arg1; _tstop = arg2; /* _tstep unchanged */ }else if (arg1 >= arg2) { /* 2 args: _tstop, _tstep */ _tstart = _sim->_last_time; _tstop = arg1; _tstep = arg2; }else{ /* arg1 < arg2 */ /* 2 args: _tstep, _tstop */ _tstart = "NA"; /* 0 */ /* spice order */ _tstop = arg2; _tstep = arg1; } }else{itested(); assert(arg1.has_hard_value()); arg1.e_val(0.,_scope); if (arg1 > _sim->_last_time) {untested(); /* 1 arg: _tstop */ _tstart = _sim->_last_time; _tstop = arg1; /* _tstep unchanged */ }else if (arg1 == 0.) {itested(); /* 1 arg: _tstart */ double oldrange = _tstop - _tstart; _tstart = 0.; _tstop = oldrange; /* _tstep unchanged */ }else{untested(); /* arg1 < _sim->_last_time, but not 0 */ /* 1 arg: _tstep */ double oldrange = _tstop - _tstart; _tstart = _sim->_last_time; _tstop = _sim->_last_time + oldrange; _tstep = arg1; } } }else{ /* no args */ double oldrange = _tstop - _tstart; _tstart = _sim->_last_time; _tstop = _sim->_last_time + oldrange; /* _tstep unchanged */ } if (Cmd.match1("'\"({") || Cmd.is_pfloat()) { Cmd >> _dtmax_in; }else{ } options(Cmd); _tstart.e_val(0., _scope); _tstop.e_val(NOT_INPUT, _scope); _tstep.e_val(NOT_INPUT, _scope); if (_cold || _tstart < _sim->_last_time || _sim->_last_time <= 0.) { _cont = false; time1 = _sim->_time0 = 0.; }else{ _cont = true; time1 = _sim->_time0 = _sim->_last_time; } _sim->_freq = ((_tstop > _tstart) ? (1 / (_tstop - _tstart)) : (0.)); if (!_tstep.has_good_value()) { throw Exception("transient: time step is required"); }else if (_tstep==0.) {itested(); throw Exception("time step = 0"); }else{ } if (_dtmax_in.has_hard_value()) { _dtmax = _dtmax_in; }else if (_skip_in.has_hard_value()) { _dtmax = _tstep / double(_skip_in); }else{ _dtmax = std::min(_dtmax_in, _tstep); } if (_dtmin_in.has_hard_value()) { _sim->_dtmin = _dtmin_in; }else if (_dtratio_in.has_hard_value()) { _sim->_dtmin = _dtmax / _dtratio_in; }else{ // use larger of soft values _sim->_dtmin = std::max(double(_dtmin_in), _dtmax/_dtratio_in); } } /*--------------------------------------------------------------------------*/ /* tr_options: set options common to transient and fourier analysis */ void TRANSIENT::options(CS& Cmd) { _out = IO::mstdout; _out.reset(); //BUG// don't know why this is needed _sim->_temp_c = OPT::temp_c; bool ploton = IO::plotset && plotlist().size() > 0; _sim->_uic = _cold = false; _trace = tNONE; unsigned here = Cmd.cursor(); do{ ONE_OF || Get(Cmd, "c{old}", &_cold) || Get(Cmd, "dte{mp}", &_sim->_temp_c, mOFFSET, OPT::temp_c) || Get(Cmd, "dtma{x}", &_dtmax_in) || Get(Cmd, "dtmi{n}", &_dtmin_in) || Get(Cmd, "dtr{atio}", &_dtratio_in) || Get(Cmd, "pl{ot}", &ploton) || Get(Cmd, "sk{ip}", &_skip_in) || Get(Cmd, "te{mperature}", &_sim->_temp_c) || Get(Cmd, "uic", &_sim->_uic) || (Cmd.umatch("tr{ace} {=}") && (ONE_OF || Set(Cmd, "n{one}", &_trace, tNONE) || Set(Cmd, "o{ff}", &_trace, tNONE) || Set(Cmd, "w{arnings}", &_trace, tUNDER) || Set(Cmd, "a{lltime}", &_trace, tALLTIME) || Set(Cmd, "r{ejected}", &_trace, tREJECTED) || Set(Cmd, "i{terations}",&_trace, tITERATION) || Set(Cmd, "v{erbose}", &_trace, tVERBOSE) || Cmd.warn(bWARNING, "need none, off, warnings, alltime, " "rejected, iterations, verbose") ) ) || outset(Cmd,&_out) ; }while (Cmd.more() && !Cmd.stuck(&here)); Cmd.check(bWARNING, "what's this?"); IO::plotout = (ploton) ? IO::mstdout : OMSTREAM(); initio(_out); _dtmax_in.e_val(BIGBIG, _scope); _dtmin_in.e_val(OPT::dtmin, _scope); _dtratio_in.e_val(OPT::dtratio, _scope); _skip_in.e_val(1, _scope); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������src/s_tr_swp.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000040357�11454012162�0014021�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: s_tr_swp.cc,v 26.136 2009/12/08 02:03:49 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * sweep time and simulate. output results. * manage event queue */ //testing=script 2007.11.22 #include "u_time_pair.h" #include "u_sim_data.h" #include "u_status.h" #include "declare.h" /* gen */ #include "s_tr.h" /*--------------------------------------------------------------------------*/ // void TRANSIENT::sweep(void); // void TRANSIENT::first(void); // bool TRANSIENT::next(void); // void TRANSIENT::accept(void); // void TRANSIENT::reject(void); /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ namespace TR { static std::string step_cause[] = { "impossible", "user requested", "event queue", "command line \"skip\"", "convergence failure, reducing (itl4)", "slow convergence, holding (itl3)", "truncation error", "ambiguous event", "limit growth", "initial guess" }; } /*--------------------------------------------------------------------------*/ void TRANSIENT::sweep() { _sim->_phase = p_INIT_DC; head(_tstart, _tstop, "Time"); _sim->_bypass_ok = false; _sim->set_inc_mode_bad(); if (_cont) { // use the data from last time _sim->_phase = p_RESTORE; _sim->restore_voltages(); CARD_LIST::card_list.tr_restore(); }else{ _sim->clear_limit(); CARD_LIST::card_list.tr_begin(); } first(); _sim->_genout = gen(); if (_sim->uic_now()) { advance_time(); _sim->zero_voltages(); CARD_LIST::card_list.do_tr(); //evaluate_models while (!_sim->_late_evalq.empty()) {itested(); //BUG// encapsulation violation _sim->_late_evalq.front()->do_tr_last(); _sim->_late_evalq.pop_front(); } _converged = true; }else{ _converged = solve_with_homotopy(OPT::DCBIAS,_trace); if (!_converged) { error(bWARNING, "did not converge\n"); }else{ } } review(); _accepted = true; accept(); { bool printnow = (_sim->_time0 == _tstart || _trace >= tALLTIME); if (printnow) { _sim->keep_voltages(); outdata(_sim->_time0); }else{untested(); } } while (next()) { _sim->_bypass_ok = false; _sim->_phase = p_TRAN; _sim->_genout = gen(); _converged = solve(OPT::TRHIGH,_trace); _accepted = _converged && review(); if (_accepted) { assert(_converged); assert(_sim->_time0 <= _time_by_user_request); accept(); if (step_cause() == scUSER) { assert(up_order(_sim->_time0-_sim->_dtmin, _time_by_user_request, _sim->_time0+_sim->_dtmin)); ++_stepno; _time_by_user_request += _tstep; /* advance user time */ }else{ } assert(_sim->_time0 < _time_by_user_request); }else{ reject(); assert(time1 < _time_by_user_request); } { bool printnow = (_trace >= tREJECTED) || (_accepted && ((_trace >= tALLTIME) || (step_cause() == scUSER && _sim->_time0+_sim->_dtmin > _tstart))); if (printnow) { _sim->keep_voltages(); outdata(_sim->_time0); }else{ } } if (!_converged && OPT::quitconvfail) {untested(); outdata(_sim->_time0); throw Exception("convergence failure, giving up"); }else{ } } } /*--------------------------------------------------------------------------*/ void TRANSIENT::set_step_cause(STEP_CAUSE C) { switch (C) { case scITER_A:untested(); case scADT:untested(); case scITER_R: case scINITIAL: case scSKIP: case scTE: case scAMBEVENT: case scEVENTQ: case scUSER: ::status.control = C; break; case scNO_ADVANCE:untested(); case scZERO:untested(); case scSMALL:itested(); case scREJECT: ::status.control += C; break; } } /*--------------------------------------------------------------------------*/ int TRANSIENT::step_cause()const { return ::status.control; } /*--------------------------------------------------------------------------*/ void TRANSIENT::first() { /* usually, _sim->_time0, time1 == 0, from setup */ assert(_sim->_time0 == time1); assert(_sim->_time0 <= _tstart); ::status.review.start(); _time_by_user_request = _sim->_time0 + _tstep; /* set next user step */ //_eq.Clear(); /* empty the queue */ while (!_sim->_eq.empty()) { _sim->_eq.pop(); } _stepno = 0; set_step_cause(scUSER); ++::status.hidden_steps; ::status.review.stop(); } /*--------------------------------------------------------------------------*/ #define check_consistency() { \ trace4("", __LINE__, newtime, almost_fixed_time, fixed_time); \ assert(almost_fixed_time <= fixed_time); \ assert(newtime <= fixed_time); \ /*assert(newtime == fixed_time || newtime <= fixed_time -_sim->_dtmin);*/ \ assert(newtime <= almost_fixed_time); \ /*assert(newtime == almost_fixed_time || newtime <= almost_fixed_time - _sim->_dtmin);*/ \ assert(newtime > time1); \ assert(newtime > reftime); \ assert(new_dt > 0.); \ assert(new_dt >= _sim->_dtmin); \ assert(newtime <= _time_by_user_request); \ /*assert(newtime == _time_by_user_request*/ \ /* || newtime < _time_by_user_request - _sim->_dtmin); */ \ } #define check_consistency2() { \ assert(newtime > time1); \ assert(new_dt > 0.); \ assert(new_dt >= _sim->_dtmin); \ assert(newtime <= _time_by_user_request); \ /*assert(newtime == _time_by_user_request */ \ /* || newtime < _time_by_user_request - _sim->_dtmin);*/ \ } /*--------------------------------------------------------------------------*/ /* next: go to next time step * Set _sim->_time0 to the next time step, store the old one in time1. * Try several methods. Take the one that gives the shortest step. */ bool TRANSIENT::next() { ::status.review.start(); double old_dt = _sim->_time0 - time1; assert(old_dt >= 0); double newtime = NEVER; double new_dt = NEVER; STEP_CAUSE new_control = scNO_ADVANCE; if (_sim->_time0 == time1) { // initial step -- could be either t==0 or continue // for the first time, just guess // make it 100x smaller than expected new_dt = std::max(_dtmax/100., _sim->_dtmin); newtime = _sim->_time0 + new_dt; new_control = scINITIAL; }else if (!_converged) { new_dt = old_dt / OPT::trstepshrink; newtime = _time_by_iteration_count = time1 + new_dt; new_control = scITER_R; }else{ double reftime; if (_accepted) { reftime = _sim->_time0; trace0("accepted"); }else{ reftime = time1; trace0("rejected"); } trace2("", step_cause(), old_dt); trace3("", time1, _sim->_time0, reftime); newtime = _time_by_user_request; new_dt = newtime - reftime; new_control = scUSER; double fixed_time = newtime; double almost_fixed_time = newtime; check_consistency(); // event queue, events that absolutely will happen // exact time. NOT ok to move or omit, even by _sim->_dtmin // some action is associated with it. if (!_sim->_eq.empty() && _sim->_eq.top() < newtime) { newtime = _sim->_eq.top(); new_dt = newtime - reftime; if (new_dt < _sim->_dtmin) { //new_dt = _sim->_dtmin; //newtime = reftime + new_dt; }else{ } new_control = scEVENTQ; fixed_time = newtime; almost_fixed_time = newtime; check_consistency(); }else{ } // device events that may not happen // not sure of exact time. will be rescheduled if wrong. // ok to move by _sim->_dtmin. time is not that accurate anyway. if (_time_by_ambiguous_event < newtime - _sim->_dtmin) { if (_time_by_ambiguous_event < time1 + 2*_sim->_dtmin) {untested(); double mintime = time1 + 2*_sim->_dtmin; if (newtime - _sim->_dtmin < mintime) {untested(); newtime = mintime; new_control = scAMBEVENT; }else{untested(); } }else{ newtime = _time_by_ambiguous_event; new_control = scAMBEVENT; } new_dt = newtime - reftime; almost_fixed_time = newtime; check_consistency(); }else{ } // device error estimates if (_time_by_error_estimate < newtime - _sim->_dtmin) { newtime = _time_by_error_estimate; new_dt = newtime - reftime; new_control = scTE; check_consistency(); }else{ } // skip parameter if (new_dt > _dtmax) { if (new_dt > _dtmax + _sim->_dtmin) { new_control = scSKIP; }else{ } new_dt = _dtmax; newtime = reftime + new_dt; check_consistency(); }else{ } // converged but with more iterations than we like if ((new_dt > (old_dt + _sim->_dtmin) * OPT::trstephold) && _sim->exceeds_iteration_limit(OPT::TRLOW)) {untested(); assert(_accepted); new_dt = old_dt * OPT::trstephold; newtime = reftime + new_dt; new_control = scITER_A; check_consistency(); }else{ } // limit growth if (_sim->analysis_is_tran_dynamic() && new_dt > old_dt * OPT::trstepgrow) {untested(); new_dt = old_dt * OPT::trstepgrow; newtime = reftime + new_dt; new_control = scADT; check_consistency(); }else{ } // quantize if (newtime < almost_fixed_time) { assert(new_dt >= 0); if (newtime > reftime + old_dt*.8 && newtime < reftime + old_dt*1.5 && reftime + old_dt <= almost_fixed_time) { // new_dt is close enough to old_dt. // use old_dt, to avoid a step change. new_dt = old_dt; newtime = reftime + new_dt; if (newtime > almost_fixed_time) {untested(); new_control = scAMBEVENT; newtime = almost_fixed_time; new_dt = newtime - reftime; }else{ } check_consistency(); }else{ // There will be a step change. // Try to choose one that we will keep for a while. // Choose new_dt to be in integer fraction of target_dt. double target_dt = fixed_time - reftime; assert(target_dt >= new_dt); double steps = 1 + floor((target_dt - _sim->_dtmin) / new_dt); assert(steps > 0); new_dt = target_dt / steps; newtime = reftime + new_dt; check_consistency(); } }else{ assert(newtime == almost_fixed_time); } // trap time step too small if (!_accepted && new_dt < _sim->_dtmin) {untested(); new_dt = _sim->_dtmin; newtime = reftime + new_dt; new_control = scSMALL; check_consistency(); }else{ } // if all that makes it close to user_requested, make it official if (up_order(newtime-_sim->_dtmin, _time_by_user_request, newtime+_sim->_dtmin)) { //newtime = _time_by_user_request; //new_dt = newtime - reftime; new_control = scUSER; check_consistency(); }else{ } check_consistency(); assert(!_accepted || newtime > _sim->_time0); assert(_accepted || newtime <= _sim->_time0); } set_step_cause(new_control); /* got it, I think */ /* check to be sure */ if (newtime < time1 + _sim->_dtmin) {itested(); /* It's really bad. */ /* Reject the most recent step, back up as much as possible, */ /* and creep along */ assert(!_accepted); assert(step_cause() < scREJECT); assert(step_cause() >= 0); error(bDANGER,"non-recoverable " + TR::step_cause[step_cause()] + "\n"); error(bDANGER, "newtime=%e rejectedtime=%e oldtime=%e using=%e\n", newtime, _sim->_time0, time1, time1 + _sim->_dtmin); newtime = time1 + _sim->_dtmin; set_step_cause(scSMALL); //check_consistency2(); throw Exception("tried everything, still doesn't work, giving up"); //}else if (newtime <= _sim->_time0 - _sim->_dtmin) { }else if (newtime < _sim->_time0) { /* Reject the most recent step. */ /* We have faith that it will work with a smaller time step. */ assert(!_accepted); assert(newtime >= time1 + _sim->_dtmin); error(bLOG, "backwards time step\n"); error(bLOG, "newtime=%e rejectedtime=%e oldtime=%e\n", newtime, _sim->_time0, time1); set_step_cause(scREJECT); _sim->mark_inc_mode_bad(); check_consistency2(); }else if (newtime < _sim->_time0 + _sim->_dtmin) {untested(); /* Another evaluation at the same time. */ /* Keep the most recent step, but creep along. */ assert(newtime > _sim->_time0 - _sim->_dtmin); error(bDANGER, "zero time step\n"); error(bDANGER, "newtime=%e rejectedtime=%e oldtime=%e\n", newtime, _sim->_time0, time1); if (_accepted) {untested(); time1 = _sim->_time0; }else{untested(); assert(_converged); } check_consistency2(); newtime = _sim->_time0 + _sim->_dtmin; if (newtime > _time_by_user_request) {untested(); newtime = _time_by_user_request; set_step_cause(scUSER); }else{untested(); } set_step_cause(scZERO); check_consistency2(); }else{ assert(_accepted); assert(newtime >= _sim->_time0 + _sim->_dtmin); /* All is OK. Moving on. */ /* Keep value of newtime */ time1 = _sim->_time0; check_consistency2(); } _sim->_time0 = newtime; /* advance event queue (maybe) */ /* We already looked at it. Dump what's on top if we took it. */ while (!_sim->_eq.empty() && _sim->_eq.top() <= _sim->_time0) { trace1("eq", _sim->_eq.top()); _sim->_eq.pop(); } while (!_sim->_eq.empty() && _sim->_eq.top() < _sim->_time0 + _sim->_dtmin) {itested(); trace1("eq-extra", _sim->_eq.top()); _sim->_eq.pop(); } //BUG// what if it is later rejected? It's lost! check_consistency2(); ++::status.hidden_steps; ++steps_total_; ::status.review.stop(); trace0("next"); return (_sim->_time0 <= _tstop + _sim->_dtmin); } /*--------------------------------------------------------------------------*/ bool TRANSIENT::review() { ::status.review.start(); _sim->count_iterations(iTOTAL); TIME_PAIR time_by = CARD_LIST::card_list.tr_review(); _time_by_error_estimate = time_by._error_estimate; // limit minimum time step // 2*_sim->_dtmin because _time[1] + _sim->_dtmin might be == _time[0]. if (time_by._event < time1 + 2*_sim->_dtmin) { _time_by_ambiguous_event = time1 + 2*_sim->_dtmin; }else{ _time_by_ambiguous_event = time_by._event; } // force advance when time too close to previous if (std::abs(_time_by_ambiguous_event - _sim->_time0) < 2*_sim->_dtmin) { _time_by_ambiguous_event = _sim->_time0 + 2*_sim->_dtmin; }else{ } if (time_by._error_estimate < time1 + 2*_sim->_dtmin) { _time_by_error_estimate = time1 + 2*_sim->_dtmin; }else{ _time_by_error_estimate = time_by._error_estimate; } if (std::abs(_time_by_error_estimate - _sim->_time0) < 1.1*_sim->_dtmin) { _time_by_error_estimate = _sim->_time0 + 1.1*_sim->_dtmin; }else{ } ::status.review.stop(); return (_time_by_error_estimate > _sim->_time0 && _time_by_ambiguous_event > _sim->_time0); } /*--------------------------------------------------------------------------*/ void TRANSIENT::accept() { ::status.accept.start(); _sim->set_limit(); if (OPT::traceload) { while (!_sim->_acceptq.empty()) { _sim->_acceptq.back()->tr_accept(); _sim->_acceptq.pop_back(); } }else{itested(); _sim->_acceptq.clear(); CARD_LIST::card_list.tr_accept(); } ++steps_accepted_; ::status.accept.stop(); } /*--------------------------------------------------------------------------*/ void TRANSIENT::reject() { ::status.accept.start(); _sim->_acceptq.clear(); ++steps_rejected_; ::status.accept.stop(); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/spice-wrapper.cc��������������������������������������������������������������������������������0000664�0000000�0000000�00000173111�11454012162�0014735�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: spice-wrapper.cc,v 26.136 2009/12/07 23:20:42 al Exp $ -*- C++ -*- * Copyright (C) 2007 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This file is distributed as is, completely without warranty or * service support. The author and its employees are not liable for * the condition or performance of the software. * * The author owns the copyright but shall not be liable for any * infringement of copyright or other proprietary rights brought by * third parties against the users of the software. * * The author hereby disclaims all implied warranties. * * This author grants the users the right to modify, copy, and * redistribute this file, for any purpose, both within the user's * organization and externally. */ //testing=script 2008.11.28 // code style comment: Use of "reinterpret_cast" is always bad style. /*--------------------------------------------------------------------------*/ // spice includes extern "C" { #define _complex CompleX #define NODE NodE #define public PubliC #define bool BooL #define main MaiN #include "capabil.h" #include "const.h" #include "iferrmsg.h" #include "devdefs.h" #include "ftedefs.h" #include "optdefs.h" #ifdef JSPICE3 #include "uflags.h" #include "inpdefs.h" #include "tskdefs.h" #endif #undef main #undef bool #undef public #undef NODE #undef _complex #undef eq #undef OPT #undef LINEAR #undef STRING #undef BOOLEAN #undef VT_BOOL #undef VT_NUM #undef VT_REAL #undef VT_STRING #undef VT_LIST } /*--------------------------------------------------------------------------*/ // gnucap includes //#include "globals.h" #include "u_xprobe.h" #include "d_subckt.h" #include "e_storag.h" #include "e_model.h" /*--------------------------------------------------------------------------*/ // customization -- must be last #include "wrapper.h" #if !defined(UNCONNECTED_NODES) #define UNCONNECTED_NODES uDISALLOW #if (MIN_NET_NODES != MAX_NET_NODES) #error "What should I do with the unconnected nodes?" #endif #endif #if !defined(VALUE_NAME) #define VALUE_NAME "#" #endif #if !defined(TAIL_SIZE) #define TAIL_SIZE 1 #endif #if !defined(IS_VALID) #define IS_VALID {return MODEL_CARD::is_valid(d);} #endif /*--------------------------------------------------------------------------*/ extern SPICEdev info; const int SPICE_INVALID_NODE = 0; const int SPICE_UNCONNECTED_NODE = -1; const int OFFSET = 1; enum {uGROUND=1, uFLOAT=2, uDISALLOW=3}; const int MATRIX_NODES = (MAX_NET_NODES + INTERNAL_NODES); class DEV_SPICE; class MODEL_SPICE; static COMMON_SUBCKT Default_Params(CC_STATIC); /*--------------------------------------------------------------------------*/ /* function mapping: see devdefs.h * DEVparam DEV_SPICE::parse_spice * DEVmodParam MODEL_SPICE::parse_params * DEVload DEV_SPICE::do_tr * DEVsetup MODEL_SPICE::precalc, DEV_SPICE::expand * DEVunsetup not used -- spice baggage -- just zeros some nodes * DEVpzSetup not used -- pole-zero * DEVtemperature DEV_SPICE::internal_precalc * DEVtrunc DEV_SPICE::tr_review * DEVfindBranch not used -- current probes for current controlled source * DEVacLoad DEV_SPICE::do_ac * DEVaccept not used -- sets break points //BUG// need for: isrc, ltra, tra, vsrc, cpl, txl * DEVdestroy not used -- spice baggage -- deletes a list * DEVmodDelete not used -- spice baggage -- delete one model * DEVdelete not used -- spice baggage -- delete one instance * DEVsetic not used -- "getic" -- initial conditions //BUG// need this * DEVask DEV_SPICE::print_args, DEV_SPICE::tr_probe_num * DEVmodAsk MODEL_SPICE::print_params, MODEL_SPICE::print_calculated * DEVpzLoad not used -- pole zero -- should use for AC * DEVconvTest DEV_SPICE::do_tr * DEVsenSetup not used -- sensitivity * DEVsenLoad not used -- sensitivity * DEVsenUpdate not used -- sensitivity * DEVsenAcLoad not used -- sensitivity * DEVsenPrint not used -- sensitivity * DEVsenTrunc not used -- sensitivity * DEVdisto not used -- distortion * DEVnoise not used -- noise */ /*--------------------------------------------------------------------------*/ union SPICE_MODEL_DATA { mutable GENmodel _gen;// generic -- use this one MODEL _full; // determines size char _space; // char pointer for fill_n SPICE_MODEL_DATA() { std::fill_n(&_space, sizeof(MODEL), '\0'); } SPICE_MODEL_DATA(const SPICE_MODEL_DATA& p) : _full(p._full) { } }; /*--------------------------------------------------------------------------*/ class MODEL_SPICE : public MODEL_CARD{ private: static int _count; static CKTcircuit _ckt; public: SPICE_MODEL_DATA _spice_model; std::string _key; std::string _level; PARAM_LIST _params; protected: explicit MODEL_SPICE(const MODEL_SPICE& p); // for clone public: explicit MODEL_SPICE(const DEV_SPICE* p); // for dispatcher ~MODEL_SPICE(); public: // override virtual MODEL_CARD* clone()const {return new MODEL_SPICE(*this);} bool is_valid(const COMPONENT* d)const IS_VALID //void expand(); void precalc_first(); public: // type void set_dev_type(const std::string& nt); std::string dev_type()const { return _key;} public: // parameters bool param_is_printable(int)const; std::string param_name(int)const; std::string param_name(int i, int j)const; std::string param_value(int)const; void set_param_by_name(std::string Name, std::string Value); void set_param_by_index(int, std::string&, int); int param_count_dont_print()const {return MODEL_CARD::param_count();} int param_count()const { return (static_cast(_params.size()) + MODEL_CARD::param_count());} void Set_param_by_name(std::string Name, std::string Value); public: // not virtual static int count() {untested(); return _count;} static CKTcircuit* ckt() {return &_ckt;} static void init_ckt(); }; /*--------------------------------------------------------------------------*/ class DEV_SPICE : public STORAGE { private: static int _count; public: private: union { mutable GENinstance _spice_instance; INSTANCE _inst; char _inst_space; }; std::string _modelname; const MODEL_SPICE* _model; const SPICE_MODEL_DATA* _spice_model; node_t _nodes[MATRIX_NODES]; COMPLEX* _matrix[MATRIX_NODES+OFFSET]; // For tran, real is now, imag is saved. COMPLEX _matrix_core[MATRIX_NODES+OFFSET][MATRIX_NODES+OFFSET]; public: double _i0[MATRIX_NODES+OFFSET]; // right side - current offsets or ac real part double _i1[MATRIX_NODES+OFFSET]; // right side - saved ......... or ac imag part double _v1[MATRIX_NODES+OFFSET]; // input voltages double* (_states[8]); // array of 8 pointers double* _states_1; int _num_states; int _maxEqNum; private: explicit DEV_SPICE(const DEV_SPICE& p); public: explicit DEV_SPICE(); ~DEV_SPICE(); protected: // override virtual char id_letter()const {untested();return SPICE_LETTER[0];} bool print_type_in_spice()const {return true;} std::string value_name()const {return VALUE_NAME;} int max_nodes()const {return MAX_NET_NODES;} int min_nodes()const {return MIN_NET_NODES;} int matrix_nodes()const {return MATRIX_NODES;} int net_nodes()const {return _net_nodes;} int int_nodes()const {return INTERNAL_NODES;} CARD* clone()const {return new DEV_SPICE(*this);} void precalc_first(); void expand(); void precalc_last(); //void map_nodes(); //ELEMENT void internal_precalc(); void tr_iwant_matrix() {tr_iwant_matrix_extended();} void tr_begin() {STORAGE::tr_begin(); internal_precalc();} void tr_restore() {STORAGE::tr_restore(); internal_precalc();} void dc_advance() {STORAGE::dc_advance(); internal_precalc();} void tr_advance(); void tr_regress(); bool tr_needs_eval()const; //void tr_queue_eval(); //ELEMENT bool do_tr(); void tr_load(); TIME_PAIR tr_review(); void tr_accept(); void tr_unload(); double tr_involts()const {unreachable();return NOT_VALID;} //double tr_input()const //ELEMENT double tr_involts_limited()const {unreachable();return NOT_VALID;} //double tr_input_limited()const //ELEMENT double tr_amps()const {itested();return NOT_VALID;} double tr_probe_num(const std::string&)const; void ac_iwant_matrix() {ac_iwant_matrix_extended();} void ac_begin(); void do_ac(); void ac_load(); COMPLEX ac_involts()const {unreachable();return NOT_VALID;} COMPLEX ac_amps()const {unreachable();return NOT_VALID;} XPROBE ac_probe_ext(const std::string&)const {itested(); return XPROBE(NOT_VALID, mtNONE);} int tail_size()const {return TAIL_SIZE;} public: // type void set_dev_type(const std::string& nt); std::string dev_type()const {return _modelname;} public: // ports // bool port_exists(int i)const //COMPONENT std::string port_name(int i)const {itested(); assert(i >= 0); assert(i < MAX_NET_NODES); return port_names[i]; } // const std::string& port_value(int i)const; //COMPONENT //void set_port_by_name(std::string& name, std::string& value); //void set_port_by_index(int index, std::string& value); private: // parameters //bool Param_exists(int i)const; // {return Param_name(i) != "";} //bool Param_is_printable(int)const; //std::string Param_name(int)const; //std::string Param_name(int i, int j)const {return STORAGE::Param_name(i, j);} //std::string Param_value(int)const; void set_param_by_name(std::string Name, std::string Value); void Set_param_by_name(std::string Name, std::string Value); void Set_param_by_index(int, std::string&, int); int param_count_dont_print()const {return common()->COMMON_COMPONENT::param_count();} private: CKTcircuit* ckt()const {return MODEL_SPICE::ckt();} void init_ckt() {MODEL_SPICE::init_ckt();} void update_ckt()const; void localize_ckt()const; int* spice_nodes()const {return &(_spice_instance.GENnode1);} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ CKTcircuit MODEL_SPICE::_ckt; /* * used as intended, copy-out, matters: CKTnoncon, CKTtroubleElt * * used as intended, func specific: CKTmode, CKTcurrentAnalysis * * used as intended, localized, matters: CKTstates, CKTdelta, CKTdeltaOld, * CKTag(broken), CKTorder(broken), CKTrhs, CKTrhsOld, CKTirhs, * CKTtimePoints(broken,ltra?) * * used as intended, updated, matters: CKTtime, CKTtemp, CKTomega * * used as intended, constant, matters: CKTnomTemp, CKTabstol, * CKTreltol, CKTvoltTol, CKTgmin, CKTsrcFact(broken), * CKTdefaultMosL, CKTdefaultMosW, CKTdefaultMosAD, CKTdefaultMosAS, * * used almost as intended, matters, probably ok: * CKTbypass: false to disable * CKTintegrateMethod: used only by Jspice -- set to 0 to disable * CKTsenInfo: used by sens, NULL to disable * CKTfixLimit(mos1236): 1 for Spice-2 mode * CKTbadMos3(mos3): false for Spice-3 mode * * misused: (not used by spice devs, use to pass gnucap stuff through) * CKTstat: the device (type DEV_SPICE) * CKTmaxEqNum: use as counter for internal nodes, pass to CKTmkVolt * * need to handle (ind): CKThead(ind,load) * need to handle (cpl,txl): CKTnodes(cpl,txl), * * need to handle ([iv]src): * CKTbreak([iv]src,accept), CKTfinalTime([iv]src,load), CKTstep([iv]src,load), * * need to handle (ltra): * CKTminBreak(ltra,tra,accept), CKTtrtol(ltra,trunc), * CKTmaxStep(ltra,temp), CKTtimeListSize(ltra,Jspice,accept), * CKTtimeIndex(ltra), CKTsizeIncr(ltra), CKTtryToCompact(ltra) * * used by "predictor": CKTagp, CKTpred, CKTsols * used by "sens": CKTirhsOld, CKTrhsOp * used by noise&distortion: CKTcurJob * * not used: CKTvt, CKTmaxOrder, CKTmatrix, CKTniState, CKTrhsSpare, * CKTirhsSpare, CKTsenRhs, CKTseniRhs, CKTlastNode, CKTnumStates, * CKTdcMaxIter, CKTdcTrcvMaxIter, CKTtranMaxIter, CKTbreakSize, CKTsaveDelta, * CKTbreaks, CKTpivotAbsTol, CKTpivotRelTol, CKTchgtol, CKTlteReltol, CKTlteAbstol, * CKTdelmin, CKTinitTime, CKTdiagGmin, CKTnumSrcSteps, CKTnumGminSteps, CKThadNodeset, * CKTnoOpIter, CKTisSetup, CKTdeltaList, CKTkeepOpInfo, CKTtroubleNode */ #define assert_ckt_initialized(ckt) { \ assert(ckt); \ assert((ckt)->CKTnomTemp == OPT::tnom_c + CONSTCtoK); \ assert(((ckt)->CKTcurrentAnalysis == DOING_DCOP) == CKT_BASE::_sim->command_is_op()); \ assert(((ckt)->CKTcurrentAnalysis == DOING_TRCV) == CKT_BASE::_sim->command_is_dc()); \ assert(((ckt)->CKTcurrentAnalysis == DOING_AC ) == CKT_BASE::_sim->analysis_is_ac()); \ assert(((ckt)->CKTcurrentAnalysis == DOING_TRAN) == CKT_BASE::_sim->analysis_is_tran()); \ assert((ckt)->CKTbypass == false); \ assert((ckt)->CKTabstol == OPT::abstol); \ assert((ckt)->CKTreltol == OPT::reltol); \ assert((ckt)->CKTvoltTol == OPT::vntol); \ assert((ckt)->CKTsrcFact == 1.); \ assert((ckt)->CKTdefaultMosL == OPT::defl); \ assert((ckt)->CKTdefaultMosW == OPT::defw); \ assert((ckt)->CKTdefaultMosAD == OPT::defad); \ assert((ckt)->CKTdefaultMosAS == OPT::defas); \ } void MODEL_SPICE::init_ckt() { assert(ckt()); ckt()->CKTtime = _sim->_time0; ckt()->CKTtemp = _sim->_temp_c + CONSTCtoK; //manage by update ckt()->CKTnomTemp = OPT::tnom_c + CONSTCtoK; ckt()->CKTintegrateMethod = 0; // disable if (_sim->command_is_op()) { ckt()->CKTcurrentAnalysis = DOING_DCOP; }else if (_sim->command_is_dc()) { ckt()->CKTcurrentAnalysis = DOING_TRCV; }else if (_sim->command_is_ac()) { ckt()->CKTcurrentAnalysis = DOING_AC; }else if (_sim->analysis_is_tran()) { ckt()->CKTcurrentAnalysis = DOING_TRAN; }else{ // probably probe ckt()->CKTcurrentAnalysis = 0; } ckt()->CKTmode = 0; // wrong but safe ckt()->CKTbypass = false; // manage this elsewhere ckt()->CKTabstol = OPT::abstol; ckt()->CKTreltol = OPT::reltol; ckt()->CKTvoltTol = OPT::vntol; ckt()->CKTgmin = OPT::gmin; ckt()->CKTsrcFact = 1.; // source stepping kluge ckt()->CKTdefaultMosL = OPT::defl; ckt()->CKTdefaultMosW = OPT::defw; ckt()->CKTdefaultMosAD = OPT::defad; ckt()->CKTdefaultMosAS = OPT::defas; ckt()->CKTfixLimit = false; // limiting kluge 1 == spice2 #ifndef JSPICE3 ckt()->CKTbadMos3 = false; // 1 = spice2 compat ckt()->CKTsenInfo = NULL; // used as flag to print sens info #endif #ifdef NGSPICE_17 ckt()->CKTdefaultMosM = 1.; ckt()->CKTcopyNodesets = false; #endif assert_ckt_initialized(ckt()); } #define assert_ckt_up_to_date(ckt) { \ assert_ckt_initialized(ckt); \ assert((ckt)->CKTtime == CKT_BASE::_sim->_time0); \ assert((ckt)->CKTtemp == CKT_BASE::_sim->_temp_c + CONSTCtoK); \ } void DEV_SPICE::update_ckt()const { assert_ckt_initialized(ckt()); ckt()->CKTgmin = OPT::gmin; ckt()->CKTstat = NULL; // mark as not localized ckt()->CKTtime = _sim->_time0; ckt()->CKTdelta = NOT_VALID; // localized ckt()->CKTtemp = _sim->_temp_c + CONSTCtoK; ckt()->CKTmode = 0; ckt()->CKTomega = _sim->_jomega.imag(); assert_ckt_up_to_date(ckt()); } #define assert_ckt_localized(ckt) { \ assert_ckt_up_to_date(ckt); \ assert((ckt)->CKTstat); \ DEV_SPICE* d = reinterpret_cast((ckt)->CKTstat);\ assert(d); \ assert(dynamic_cast(d)); \ assert((ckt)->CKTdelta == d->_dt); \ if (d->_dt == 0) {untested(); \ assert((ckt)->CKTag[0] == 0); \ assert((ckt)->CKTorder == 1); \ }else if (d->_time[1] != 0 && d->_method_a == mTRAP) { \ assert(conchk((ckt)->CKTag[0], 2 / d->_dt)); \ assert((ckt)->CKTorder == 2); \ }else{ \ assert(conchk((ckt)->CKTag[0], 1 / d->_dt)); \ assert((ckt)->CKTorder == 1); \ } \ assert((ckt)->CKTag[0] == (ckt)->CKTag[0]); \ assert((ckt)->CKTrhs == d->_i0); \ assert((ckt)->CKTrhsOld == d->_v1); \ assert((ckt)->CKTirhs == d->_i1); \ assert((ckt)->CKTtimePoints == d->_time); \ } void DEV_SPICE::localize_ckt()const { assert_ckt_up_to_date(ckt()); ckt()->CKTstat = reinterpret_cast(const_cast(this)); assert(OPT::_keep_time_steps <= 8); for (int ii=0; ii<8; ++ii) { ckt()->CKTstates[ii] = _states[ii]; } //assert(ckt()->CKTtime == _time[0]); //BUG// can fail in ac ckt()->CKTdelta = _dt; for (int ii=0; iiCKTdeltaOld[ii] = _time[ii] - _time[ii+1]; } assert(_dt == NOT_VALID || conchk(ckt()->CKTdelta, ckt()->CKTdeltaOld[0])); //ckt()->CKTag[0] = tr_c_to_g(1, ckt()->CKTag[0]); // defer fixing this -- GEAR not here if (_dt == 0) {untested(); ckt()->CKTag[1] = ckt()->CKTag[0] = 0; ckt()->CKTorder = 1; }else if (_time[1] != 0 && _method_a == mTRAP) { ckt()->CKTag[0] = 2 / _dt; ckt()->CKTag[1] = 1; ckt()->CKTorder = 2; }else{ ckt()->CKTag[0] = 1 / _dt; ckt()->CKTag[1] = -1 / _dt; ckt()->CKTorder = 1; } ckt()->CKTrhs = const_cast(_i0); ckt()->CKTrhsOld = const_cast(_v1); ckt()->CKTirhs = const_cast(_i1); ckt()->CKTmode = 0; ckt()->CKTtimePoints = const_cast(_time); assert_ckt_localized(ckt()); } #define assert_model_raw() { \ assert(_spice_model._gen.GENmodType == 0); \ assert(_spice_model._gen.GENnextModel == NULL); \ assert(_spice_model._gen.GENinstances == NULL); \ } #define assert_model_unlocalized() { \ assert(_model->_spice_model._gen.GENinstances == NULL);\ assert(_spice_model); \ assert(_spice_model->_gen.GENmodType == 0); \ assert(_spice_model->_gen.GENnextModel == NULL); \ assert(_spice_model->_gen.GENinstances == NULL); \ assert(_spice_model->_gen.GENmodName); \ } #define assert_model_localized() { \ assert(_spice_model); \ assert(_spice_model->_gen.GENmodType == 0); \ assert(_spice_model->_gen.GENnextModel == NULL); \ assert(_spice_model->_gen.GENinstances); \ assert(_spice_model->_gen.GENmodName); \ } #define assert_instance() { \ assert(_spice_instance.GENnextInstance == NULL); \ assert(_spice_instance.GENname == NULL); \ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ struct IFVA { IFvalue* _v; int _type; IFVA(IFvalue* v, int t) :_v(v), _type(t) {assert(v);} void operator=(const std::string& s) { CS cmd(CS::_STRING, s); assert(_v); int datatype = _type; if (datatype & IF_SET) { if (datatype & IF_VECTOR) {untested(); incomplete(); }else{ } switch (datatype & 0xff) { case IF_FLAG: _v->iValue = true; break; case IF_INTEGER: cmd >> _v->iValue; break; case IF_REAL: cmd >> _v->rValue; break; case IF_COMPLEX:untested(); //cmd >> _v->cValue; incomplete(); break; case IF_NODE:untested(); incomplete(); break; case IF_STRING: { //assert(!(_v->sValue)); //BUG//memory leak -- this is never deleted _v->sValue = new char[s.length()+1]; strcpy(_v->sValue, s.c_str()); break; } case IF_INSTANCE: untested(); incomplete(); break; case IF_PARSETREE:untested(); incomplete(); break; default: unreachable(); break; } }else{untested(); } } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ MODEL_SPICE::MODEL_SPICE(const DEV_SPICE* p) :MODEL_CARD(p), _spice_model(), _key(), _level(), _params() { assert_model_raw(); } /*--------------------------------------------------------------------------*/ MODEL_SPICE::MODEL_SPICE(const MODEL_SPICE& p) :MODEL_CARD(p), _spice_model(p._spice_model), _key(p._key), _level(p._level), _params(p._params) { assert_model_raw(); } /*--------------------------------------------------------------------------*/ MODEL_SPICE::~MODEL_SPICE() { --_count; } /*--------------------------------------------------------------------------*/ void MODEL_SPICE::Set_param_by_name(std::string Name, std::string new_value) { assert_model_raw(); assert(info.DEVpublic.numModelParms); assert(info.DEVpublic.modelParms); assert(info.DEVmodParam); int num_params = *(info.DEVpublic.numModelParms); for (int i = 0; i < num_params; ++i) { IFparm Parms = info.DEVpublic.modelParms[i]; if (Name == Parms.keyword) { IFvalue Value; IFVA v(&Value, Parms.dataType); v = new_value; int ok = info.DEVmodParam(Parms.id, &Value, &_spice_model._gen); assert(ok == OK); return; }else{ } } if (Name != "level") { throw Exception_No_Match(Name); }else{ } } /*--------------------------------------------------------------------------*/ void MODEL_SPICE::set_param_by_name(std::string Name, std::string Value) { if (OPT::case_insensitive) { notstd::to_lower(&Name); }else{ } _params.set(Name, Value); Set_param_by_name(Name, to_string(_params[Name].e_val(1,scope()))); } /*--------------------------------------------------------------------------*/ void MODEL_SPICE::precalc_first() { MODEL_CARD::precalc_first(); Set_param_by_name(_key, "1"); // push down parameters into raw spice data for (PARAM_LIST::iterator i = _params.begin(); i != _params.end(); ++i) { if (i->second.has_hard_value()) { try { Set_param_by_name(i->first, to_string(i->second.e_val(1,scope()))); }catch (Exception_No_Match&) { error(bTRACE, long_label() + ": bad parameter: " + i->first + ", ignoring\n"); } }else{ } } init_ckt(); if (info.DEVsetup) { assert_model_raw(); int ok = info.DEVsetup(NULL, &_spice_model._gen, ckt(), NULL); assert(ok == OK); }else{untested(); } } /*--------------------------------------------------------------------------*/ void MODEL_SPICE::set_dev_type(const std::string& new_type) { assert_model_raw(); //_spice_model._gen.set_mod_name(short_label()); std::string s = short_label(); char* p = new char[s.length()+1]; //BUG//memory leak s.copy(p, std::string::npos); p[s.length()] = '\0'; _spice_model._gen.GENmodName = p; _key = new_type; if (OPT::case_insensitive) { notstd::to_lower(&_key); }else{ } } /*--------------------------------------------------------------------------*/ bool MODEL_SPICE::param_is_printable(int i)const { assert(i < MODEL_SPICE::param_count()); if (i >= MODEL_CARD::param_count()) { return _params.is_printable(MODEL_SPICE::param_count() - 1 - i); }else{ return MODEL_CARD::param_is_printable(i); } } /*--------------------------------------------------------------------------*/ std::string MODEL_SPICE::param_name(int i)const { assert(i < MODEL_SPICE::param_count()); if (i >= MODEL_CARD::param_count()) { return _params.name(MODEL_SPICE::param_count() - 1 - i); }else{ return MODEL_CARD::param_name(i); } } /*--------------------------------------------------------------------------*/ std::string MODEL_SPICE::param_name(int i, int j)const {untested(); assert(i < MODEL_SPICE::param_count()); if (j == 0) {untested(); return param_name(i); }else if (i >= MODEL_CARD::param_count()) {untested(); return ""; }else{untested(); return MODEL_CARD::param_name(i); } } /*--------------------------------------------------------------------------*/ std::string MODEL_SPICE::param_value(int i)const { assert(i < MODEL_SPICE::param_count()); if (i >= MODEL_CARD::param_count()) { return _params.value(MODEL_SPICE::param_count() - 1 - i); }else{ return MODEL_CARD::param_value(i); } } /*--------------------------------------------------------------------------*/ void MODEL_SPICE::set_param_by_index(int, std::string&, int) {untested(); unreachable(); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ DEV_SPICE::DEV_SPICE() :STORAGE(), _inst(), _modelname(""), _model(NULL), _spice_model(NULL), _nodes(), _matrix(), _matrix_core(), _i0(), _i1(), _v1(), _states_1(NULL), _num_states(0), _maxEqNum(0) { attach_common(&Default_Params); std::fill_n(&_inst_space, sizeof(INSTANCE), '\0'); assert_instance(); { int* node = spice_nodes(); for (int ii = 0; ii < matrix_nodes(); ++ii) { node[ii] = SPICE_INVALID_NODE; } } _n = _nodes; for (int ii = 0; ii < matrix_nodes(); ++ii) { assert(!(_n[ii].n_())); } for (int ii = 0; ii < matrix_nodes()+OFFSET; ++ii) { _matrix[ii] = _matrix_core[ii]; assert(_matrix[ii]); } assert(OPT::_keep_time_steps <= 8); for (int ii=0; ii<8; ++ii) { _states[ii] = NULL; } ++_count; assert_instance(); } /*--------------------------------------------------------------------------*/ DEV_SPICE::DEV_SPICE(const DEV_SPICE& p) :STORAGE(p), _inst(p._inst), _modelname(p._modelname), _model(p._model), _spice_model(p._spice_model), _nodes(), _matrix(), _matrix_core(), _i0(), _i1(), _v1(), _states_1(NULL), _num_states(p._num_states), _maxEqNum(p._maxEqNum) { assert_instance(); { int* node = spice_nodes(); for (int ii = 0; ii < matrix_nodes(); ++ii) { assert(node[ii] == SPICE_INVALID_NODE); } } _n = _nodes; for (int ii = 0; ii < matrix_nodes(); ++ii) { _n[ii] = p._n[ii]; } for (int ii = 0; ii < matrix_nodes()+OFFSET; ++ii) { _matrix[ii] = _matrix_core[ii]; assert(_matrix[ii]); } assert(OPT::_keep_time_steps <= 8); for (int ii=0; ii<8; ++ii) { _states[ii] = NULL; } ++_count; assert_instance(); } /*--------------------------------------------------------------------------*/ DEV_SPICE::~DEV_SPICE() { assert_instance(); --_count; if (_states[0]) { // regular instances for (int ii=0; iiCOMMON_COMPONENT::Set_param_by_name(Name, new_value); } /*--------------------------------------------------------------------------*/ void DEV_SPICE::set_param_by_name(std::string Name, std::string Value) { if (OPT::case_insensitive) { notstd::to_lower(&Name); }else{ } COMPONENT::set_param_by_name(Name, Value); COMMON_SUBCKT* c = dynamic_cast(mutable_common()); assert(c); Set_param_by_name(Name, to_string(c->_params[Name].e_val(1,scope()))); } /*--------------------------------------------------------------------------*/ void DEV_SPICE::Set_param_by_index(int i, std::string& new_value, int offset) { assert_instance(); assert(info.DEVpublic.numInstanceParms); assert(info.DEVpublic.instanceParms); assert(info.DEVparam); int num_params = *(info.DEVpublic.numInstanceParms); if (i < num_params) { IFparm Parms = info.DEVpublic.instanceParms[i]; IFvalue Value; IFVA v(&Value, Parms.dataType); v = new_value; #ifdef JSPICE3 int ok = info.DEVparam(ckt(), Parms.id, &Value, &_spice_instance, NULL); #else int ok = info.DEVparam(Parms.id, &Value, &_spice_instance, NULL); #endif assert(ok == OK); }else{untested(); STORAGE::set_param_by_index(i-num_params, new_value, offset+num_params); } assert_instance(); } /*--------------------------------------------------------------------------*/ void DEV_SPICE::expand() { assert_instance(); assert(info.DEVsetup); STORAGE::expand(); init_ckt(); { //-------- fix up external nodes int* node = spice_nodes(); for (int ii = 0; ii < net_nodes(); ++ii) { node[ii] = ii+OFFSET; } if (UNCONNECTED_NODES == uGROUND) { for (int ii = net_nodes(); ii < max_nodes(); ++ii) {itested(); node[ii] = ii+OFFSET; } }else if (UNCONNECTED_NODES == uFLOAT) { for (int ii = net_nodes(); ii < max_nodes(); ++ii) {untested(); node[ii] = SPICE_UNCONNECTED_NODE; } }else{ assert(UNCONNECTED_NODES == uDISALLOW); assert(min_nodes() == max_nodes()); assert(net_nodes() == max_nodes()); } ckt()->CKTmaxEqNum = max_nodes(); for (int ii = max_nodes(); ii < matrix_nodes(); ++ii) { node[ii] = 0; } } { //------- attach model, set up matrix pointers _model = dynamic_cast(find_model(_modelname)); if (!_model) { throw Exception_Model_Type_Mismatch(long_label(), _modelname, DEVICE_TYPE); }else{ SMPmatrix* matrix = reinterpret_cast(_matrix); _num_states = 0; _spice_instance.GENmodPtr = &(_model->_spice_model._gen); _spice_model = &(_model->_spice_model); SPICE_MODEL_DATA spice_model_copy(*_spice_model); spice_model_copy._gen.GENinstances = &_spice_instance; //------------- int ok = info.DEVsetup(matrix, &(spice_model_copy._gen), ckt(), &_num_states); // memory pointer setup, and sets _num_states // undesired side effects: sets values, messes up model //------------- assert(ok == OK); _maxEqNum = ckt()->CKTmaxEqNum; trace1("expand", ckt()->CKTmaxEqNum); assert_model_unlocalized(); } } //-------- allocate state vectors if (!_states[0]) { for (int ii=0; iiis_first_expand()) { int start_internal = 0; if (UNCONNECTED_NODES == uGROUND) { for (int ii = net_nodes(); ii < max_nodes(); ++ii) {itested(); _n[ii].set_to_ground(this); } start_internal = max_nodes(); }else{ assert(UNCONNECTED_NODES == uDISALLOW || UNCONNECTED_NODES == uFLOAT); start_internal = net_nodes(); } assert(start_internal != 0); int* node = spice_nodes(); // treat as array char fake_name[] = "a"; for (int ii = start_internal; ii < matrix_nodes(); ++ii) { if (node[ii] >= start_internal+OFFSET) { // real internal node _n[ii].new_model_node('.' + long_label() + '.' + fake_name, this); trace1("new int", node[ii]); assert(_n[ii].n_()); }else if (node[ii] >= 0+OFFSET) { // collapsed to an external node _n[ii] = _n[node[ii]-OFFSET]; trace1("collapse", node[ii]); assert(_n[ii].n_()); }else{ // not assigned trace1("not used", node[ii]); assert(!_n[ii].n_()); } ++(*fake_name); } for (int ii = 0; ii < matrix_nodes(); ++ii) { trace2((_n[ii].n_()) ? (_n[ii].n_()->short_label().c_str()) : ("NULL"), ii, node[ii]); } // This could be one loop, but doing it this way gives more info. for (int ii = 0; ii < min_nodes(); ++ii) { assert(_n[ii].n_()); } for (int ii = min_nodes(); ii < net_nodes(); ++ii) { assert(_n[ii].n_()); } for (int ii = net_nodes(); ii < max_nodes(); ++ii) {itested(); //assert(_n[ii].n_()); } for (int ii = max_nodes(); ii < matrix_nodes(); ++ii) { assert(_n[ii].n_() || !node[ii]); } }else{untested(); } assert_model_unlocalized(); assert_instance(); } /*--------------------------------------------------------------------------*/ void DEV_SPICE::precalc_first() { STORAGE::precalc_first(); // push down parameters into spice data COMMON_SUBCKT* c = dynamic_cast(mutable_common()); assert(c); for (PARAM_LIST::iterator i = c->_params.begin(); i != c->_params.end(); ++i) { if (i->second.has_hard_value()) { try { Set_param_by_name(i->first, to_string(i->second.e_val(1,scope()))); }catch (Exception_No_Match&) { error(bTRACE, long_label() + ": bad parameter: " + i->first + ", ignoring\n"); } }else{ } } } /*--------------------------------------------------------------------------*/ void DEV_SPICE::precalc_last() { assert(_model); assert_instance(); assert(info.DEVsetup); STORAGE::precalc_last(); init_ckt(); int* node = spice_nodes(); // treat as array // int node_stash[MATRIX_NODES]; // notstd::copy_n(node, matrix_nodes(), node_stash); // save the real nodes { //-------- fix up external nodes, again ........ // put the originals back, so DEVsetup can mess them up the same as last time int* node = spice_nodes(); for (int ii = 0; ii < net_nodes(); ++ii) { node[ii] = ii+OFFSET; } if (UNCONNECTED_NODES == uGROUND) { for (int ii = net_nodes(); ii < max_nodes(); ++ii) {itested(); node[ii] = ii+OFFSET; } }else if (UNCONNECTED_NODES == uFLOAT) { for (int ii = net_nodes(); ii < max_nodes(); ++ii) {untested(); node[ii] = SPICE_UNCONNECTED_NODE; } }else{ assert(UNCONNECTED_NODES == uDISALLOW); assert(min_nodes() == max_nodes()); assert(net_nodes() == max_nodes()); } ckt()->CKTmaxEqNum = max_nodes(); for (int ii = max_nodes(); ii < matrix_nodes(); ++ii) { node[ii] = 0; } } { SMPmatrix* matrix = reinterpret_cast(_matrix); int num_states_garbage = 0; assert(_spice_model == &(_model->_spice_model)); SPICE_MODEL_DATA spice_model_copy(*_spice_model); spice_model_copy._gen.GENinstances = &_spice_instance; int ok = info.DEVsetup(matrix, &(spice_model_copy._gen), ckt(), &num_states_garbage); assert(ok == OK); assert(num_states_garbage == _num_states); trace3("precalc", maxEqNum_stash, ckt()->CKTmaxEqNum, (maxEqNum_stash == ckt()->CKTmaxEqNum)); assert(_maxEqNum == ckt()->CKTmaxEqNum); notstd::copy_n(node_stash, matrix_nodes(), node); // put back real nodes // hopefully, the matrix pointers are the same as last time! } assert(!is_constant()); assert_model_unlocalized(); assert_instance(); } /*--------------------------------------------------------------------------*/ void DEV_SPICE::internal_precalc() { update_ckt(); if (info.DEVtemperature) { assert_instance(); assert_model_unlocalized(); _spice_model->_gen.GENinstances = &_spice_instance; assert_model_localized(); // ELEMENT::precalc(); .. don't call .. more analysis needed //----- int ok = info.DEVtemperature(&(_spice_model->_gen), ckt()); assert(ok == OK); //----- set_converged(); _spice_model->_gen.GENinstances = NULL; assert(!is_constant()); assert_instance(); }else{ } assert_model_unlocalized(); } /*--------------------------------------------------------------------------*/ void DEV_SPICE::tr_advance() { STORAGE::tr_advance(); update_ckt(); double* t = _states[OPT::_keep_time_steps-1]; for (int ii = OPT::_keep_time_steps-1; ii > 0; --ii) { _states[ii] = _states[ii-1]; } _states[0] = t; notstd::copy_n(_states[1], _num_states, _states[0]); } /*--------------------------------------------------------------------------*/ void DEV_SPICE::tr_regress() { ELEMENT::tr_regress(); update_ckt(); } /*--------------------------------------------------------------------------*/ bool DEV_SPICE::tr_needs_eval()const { if (is_q_for_eval()) { return false; }else if (!converged()) { return true; }else if (_sim->is_advance_iteration()) { return true; }else if (_time[1] == 0) { //BUG// needed for ngspice jfet, but not for spice3f5 jfet return true; }else{ int* node = spice_nodes(); // check the node voltages, reference to ground for (int ii=0; ii= 0); localize_ckt(); assert_model_unlocalized(); _spice_model->_gen.GENinstances = &_spice_instance; assert_model_localized(); if (_sim->analysis_is_tran_dynamic()) { if ((_time[1] == 0) && _sim->is_first_iteration()) { ckt()->CKTmode = MODETRAN | MODEINITTRAN; }else{ ckt()->CKTmode = MODETRAN | MODEINITFLOAT; } }else{ if (_sim->analysis_is_tran_static()) { ckt()->CKTmode = MODETRANOP; }else if (_sim->analysis_is_tran_restore()) { ckt()->CKTmode = MODETRAN; }else if (_sim->command_is_dc()) { ckt()->CKTmode = MODEDCTRANCURVE; }else if (_sim->command_is_op()) { ckt()->CKTmode = MODEDCOP; }else{unreachable(); ckt()->CKTmode = 0; } if (_sim->uic_now()) { ckt()->CKTmode |= MODEINITFIX; ckt()->CKTmode |= MODEUIC; }else if (_sim->is_initial_step()) { ckt()->CKTmode |= MODEINITJCT; }else{ ckt()->CKTmode |= MODEINITFLOAT; } } { // copy in int* node = spice_nodes(); assert(ckt()->CKTrhsOld == _v1); std::fill_n(_v1, matrix_nodes()+OFFSET, 0); for (int ii = 0; ii < matrix_nodes(); ++ii) { if (node[ii] != SPICE_INVALID_NODE) { _v1[node[ii]] = _n[ii].v0(); }else{ } } } { // clear for copy out ckt()->CKTtroubleElt = NULL; ckt()->CKTnoncon = 0; assert(ckt()->CKTrhs == _i0); std::fill_n(_i0, matrix_nodes()+OFFSET, 0); for (int ii = 0; ii < matrix_nodes()+OFFSET; ++ii) { for (int jj = 0; jj < matrix_nodes()+OFFSET; ++jj) { _matrix[ii][jj].real() = 0; } } } // do the work -- it might also do convergence checking, might not //----- info.DEVload(&(_spice_model->_gen), ckt()); //----- // convergence check -- gnucap method set_converged(ckt()->CKTnoncon == 0); for (int ii = 0; ii < _num_states; ++ii) { set_converged(converged() && conchk(_states[0][ii], _states_1[ii])); trace3("", ii, _states_1[ii], _states[0][ii]); _states_1[ii] = _states[0][ii]; } for (int ii = 0; converged() && ii < matrix_nodes()+OFFSET; ++ii) { set_converged(conchk(_i0[ii], _i1[ii])); } for (int ii = 0; converged() && ii < matrix_nodes()+OFFSET; ++ii) { for (int jj = 0; converged() && jj < matrix_nodes()+OFFSET; ++jj) { set_converged(conchk(_matrix[ii][jj].real(), _matrix[ii][jj].imag())); } } // convergence check -- Spice method // not sure if it is worth the effort if (converged() && info.DEVconvTest) { ckt()->CKTnoncon = 0; ckt()->CKTrhs = _v1; // Spice overlaps _i0 with _v1 as CKTrhs info.DEVconvTest(&(_spice_model->_gen), ckt()); set_converged(ckt()->CKTnoncon == 0); }else{ // either no separate test or already failed } bool needs_load = !converged(); for (int ii = 0; !needs_load && ii < matrix_nodes()+OFFSET; ++ii) { needs_load = !conchk(_i0[ii], _i1[ii], 0, OPT::reltol*OPT::loadtol); } for (int ii = 0; !needs_load && ii < matrix_nodes()+OFFSET; ++ii) { for (int jj = 0; !needs_load && jj < matrix_nodes()+OFFSET; ++jj) { needs_load = !conchk(_matrix[ii][jj].real(), _matrix[ii][jj].imag(), 0, OPT::reltol*OPT::loadtol); } } if (needs_load) { q_load(); }else{ } assert_model_localized(); _spice_model->_gen.GENinstances = NULL; assert_model_unlocalized(); return converged(); } /*--------------------------------------------------------------------------*/ void DEV_SPICE::tr_load() { #ifndef NDEBUG if (_loaditer == _sim->iteration_tag()) {untested(); error(bDANGER, long_label() + " internal error: double load\n"); } _loaditer = _sim->iteration_tag(); #endif int ihit[MATRIX_NODES+OFFSET]; int jhit[MATRIX_NODES+OFFSET]; std::fill_n(ihit, matrix_nodes()+OFFSET, 0); std::fill_n(jhit, matrix_nodes()+OFFSET, 0); int* node = spice_nodes(); for (int ii = 0; ii < matrix_nodes(); ++ii) { int ni = node[ii]; if (ni && !ihit[ni]) { ihit[ni] = 1; int nii = ni-OFFSET; trace4("", ii, ni, _i0[ni], _i1[ni]); tr_load_source_point(_n[ii], &(_i0[ni]), &(_i1[ni])); for (int jj = 0; jj < matrix_nodes(); ++jj) { int nj = node[jj]; if (nj && jhit[nj] != ni) { jhit[nj] = ni; int njj = nj-OFFSET; trace2("", jj, nj); trace2("", _matrix[nii][njj].real(), _matrix[nii][njj].imag()); tr_load_point(_n[ii], _n[jj], &(_matrix[nii][njj].real()), &(_matrix[nii][njj].imag())); }else{ trace2("skip", jj, nj); } } }else{ trace2("=========skip", ii, ni); } } } /*--------------------------------------------------------------------------*/ void DEV_SPICE::tr_unload() {untested();incomplete(); for (int ii = 0; ii < matrix_nodes(); ++ii) {untested(); for (int jj = 0; jj < matrix_nodes(); ++jj) {untested(); _matrix[ii][jj].real() = 0; } } _sim->mark_inc_mode_bad(); tr_load(); } /*--------------------------------------------------------------------------*/ TIME_PAIR DEV_SPICE::tr_review() { // not calling STORAGE::tr_review(); if (info.DEVtrunc) { localize_ckt(); assert_instance(); //q_accept(); assert_model_unlocalized(); _spice_model->_gen.GENinstances = &_spice_instance; assert_model_localized(); ckt()->CKTtroubleElt = NULL; double timestep = NEVER; //----- info.DEVtrunc(&(_spice_model->_gen), ckt(), ×tep); //----- _time_by._error_estimate = tr_review_check_and_convert(timestep); _time_by._event = NEVER; _spice_model->_gen.GENinstances = NULL; assert_model_unlocalized(); return _time_by; }else{ return TIME_PAIR(NEVER,NEVER); } } /*--------------------------------------------------------------------------*/ void DEV_SPICE::tr_accept() { assert_model_unlocalized(); _spice_model->_gen.GENinstances = &_spice_instance; assert_model_localized(); //STORAGE::tr_accept(); // doesn't do anything if (_sim->analysis_is_dcop() || _sim->analysis_is_ac()) { localize_ckt(); // don't copy in assert(ckt()->CKTrhsOld == _v1); // _v1 already has correct values // _n[ii].v0() is not correct -- may have been cleared ckt()->CKTmode = MODEINITSMSIG; info.DEVload(&(_spice_model->_gen), ckt()); }else{itested(); } assert_model_localized(); _spice_model->_gen.GENinstances = NULL; assert_model_unlocalized(); } /*--------------------------------------------------------------------------*/ double DEV_SPICE::tr_probe_num(const std::string& x)const { localize_ckt(); assert_ckt_up_to_date(ckt()); assert_instance(); // all of the "states" in state array int num_probe_states = std::min(_num_states, int(sizeof(state_names)/sizeof(std::string))); for (int ii=0; ii= 0); assert_model_unlocalized(); _spice_model->_gen.GENinstances = &_spice_instance; assert_model_localized(); localize_ckt(); ckt()->CKTmode = MODEAC; ckt()->CKTomega = _sim->_jomega.imag(); // clear for copy out ckt()->CKTtroubleElt = NULL; std::fill_n(_i0, matrix_nodes()+OFFSET, 0); std::fill_n(_i1, matrix_nodes()+OFFSET, 0); for (int ii = 0; ii < matrix_nodes()+OFFSET; ++ii) { for (int jj = 0; jj < matrix_nodes()+OFFSET; ++jj) { _matrix[ii][jj] = 0; } } if (info.DEVpzLoad) { info.DEVpzLoad(&(_spice_model->_gen), ckt(), reinterpret_cast(&_sim->_jomega)); }else if (info.DEVacLoad) { info.DEVacLoad(&(_spice_model->_gen), ckt()); }else{unreachable(); // nothing } assert_model_localized(); _spice_model->_gen.GENinstances = NULL; assert_model_unlocalized(); }else{untested(); // there is no acLoad function } } /*--------------------------------------------------------------------------*/ void DEV_SPICE::ac_load() { if (info.DEVacLoad) { assert_ckt_up_to_date(ckt()); int ihit[MATRIX_NODES+OFFSET]; int jhit[MATRIX_NODES+OFFSET]; std::fill_n(ihit, matrix_nodes()+OFFSET, 0); std::fill_n(jhit, matrix_nodes()+OFFSET, 0); int* node = spice_nodes(); for (int ii = 0; ii < matrix_nodes(); ++ii) { int ni = node[ii]; if (ni && !ihit[ni]) { ihit[ni] = 1; int nii = ni-OFFSET; trace3("", ii, ni, nii); ac_load_source_point(_n[ii], COMPLEX(_i0[node[ni]], _i1[node[ni]])); for (int jj = 0; jj < matrix_nodes(); ++jj) { int nj = node[jj]; if (nj && jhit[nj] != ni) { jhit[nj] = ni; int njj = nj-OFFSET; trace3("", jj, nj, njj); trace2("", _matrix[nii][njj].real(), _matrix[nii][njj].imag()); ac_load_point(_n[ii], _n[jj], _matrix[nii][njj]); }else{ trace2("skip", jj, nj); } } }else{ trace2("=========skip", ii, ni); } } }else{ // there is no acLoad function } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ extern "C" { // needed to satisfy references. Supposedly unreachable. Stubs. char *errMsg = NULL; char *errRtn = NULL; char* tmalloc(int size) {itested(); return static_cast(calloc(size,1));} char* trealloc(char*, int) {untested();incomplete(); return NULL;} //DEVnoise void txfree(char *ptr) { if (ptr) {itested(); free(ptr); }else{untested(); } } static class FT_CURCKT : public circ { TSKtask junk; public: FT_CURCKT() { junk.jobs = NULL; ci_curTask = reinterpret_cast(&junk); //::ft_curckt = this; } } stupid_ft_circ_pointer_to_pointer_hack; circ *ft_curckt = &stupid_ft_circ_pointer_to_pointer_hack; IFuid CKTnodName(CKTcircuit*,int) {incomplete();return IFuid();} //DEVsenPrint double D1i2F1(double, double, double) {incomplete(); return NOT_VALID;} //DEVdisto double D1i3F1(double, double, double, double, double, double) {incomplete(); return NOT_VALID;} double D1iF12(double, double, double, double, double) {incomplete(); return NOT_VALID;} double D1i2F12(double, double, double, double, double, double, double, double, double, double) {incomplete(); return NOT_VALID;} double D1n2F1(double, double, double) {incomplete(); return NOT_VALID;} double D1n3F1(double, double, double, double, double, double) {incomplete(); return NOT_VALID;} double D1nF12(double, double, double, double, double) {incomplete(); return NOT_VALID;} double D1n2F12(double, double, double, double, double, double, double, double, double, double) {incomplete(); return NOT_VALID;} double DFn2F1(double, double, double, double, double, double, double, double, double, double, double, double) {incomplete(); return NOT_VALID;} double DFi2F1(double, double, double, double, double, double, double, double, double, double, double, double) {incomplete(); return NOT_VALID;} double DFi3F1(double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double) {incomplete(); return NOT_VALID;} double DFn3F1(double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double) {incomplete(); return NOT_VALID;} double DFnF12(double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double) {incomplete(); return NOT_VALID;} double DFiF12(double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double) {incomplete(); return NOT_VALID;} struct DpassStr; //DEVdisto double DFn2F12(DpassStr*) {incomplete(); return NOT_VALID;} double DFi2F12(DpassStr*) {incomplete(); return NOT_VALID;} struct Dderivs; void AtanDeriv(Dderivs*, Dderivs*) {incomplete();} //DEVdisto void CosDeriv(Dderivs*, Dderivs*) {incomplete();} //DEVdisto void CubeDeriv(Dderivs*, Dderivs*) {incomplete();} //DEVdisto void DivDeriv(Dderivs*, Dderivs*, Dderivs*) {incomplete();} //DEVdisto void EqualDeriv(Dderivs*, Dderivs*) {incomplete();} //DEVdisto void ExpDeriv(Dderivs*, Dderivs*) {incomplete();} //DEVdisto void InvDeriv(Dderivs*, Dderivs*) {incomplete();} //DEVdisto void MultDeriv(Dderivs*, Dderivs*, Dderivs*) {incomplete();} //DEVdisto void PlusDeriv(Dderivs*, Dderivs*, Dderivs*) {incomplete();} //DEVdisto void PowDeriv(Dderivs*, Dderivs*, double) {incomplete();} //DEVdisto void SqrtDeriv(Dderivs*, Dderivs*) {incomplete();} //DEVdisto void TanDeriv(Dderivs*, Dderivs*) {incomplete();} //DEVdisto void TimesDeriv(Dderivs*, Dderivs*, double) {incomplete();} //DEVdisto #ifdef JSPICE3 double Nintegrate(double, double, double, GENERIC*) {incomplete(); return NOT_VALID;} //DEVnoise #else double Nintegrate(double, double, double, Ndata*) {incomplete(); return NOT_VALID;} //DEVnoise #endif void NevalSrc(double*, double*, CKTcircuit*, int, int, int, double) {incomplete();} //DEVnoise void NevalSrc2(double*, double*, CKTcircuit*, int, int, int, double, double) {incomplete();} //------------------------------------------------ // should be constants, but spice wants them to be variables. double CONSTroot2(sqrt(2.)); double CONSTvt0(P_CELSIUS0*P_K_Q); double CONSTKoverQ(P_K_Q); double CONSTe(M_E); //------------------------------------------------ // ngspice baggage int ARCHme = 0; // jspice baggage IFsimulator *ft_sim; //------------------------------------------------ //------------------------------------------------ int IFerror(int flags, char* format, IFuid* names) /* output an error or warning message */ {itested(); static struct mesg { const char *string; long flag; } msgs[] = { { "Warning", ERR_WARNING } , { "Fatal error", ERR_FATAL } , { "Panic", ERR_PANIC } , { "Note", ERR_INFO } , { NULL, 0 } } ; struct mesg *m; char buf[10000], *s, *bptr; int nindex = 0; for (m = msgs; m->flag; m++) { if (flags & m->flag) { error(bDANGER, "%s: ", m->string); }else{ } } for (s = format, bptr = buf; *s; s++) { if (*s == '%' && (s == format || *(s-1) != '%') && *(s+1) == 's') { if (names[nindex]) { strcpy(bptr, reinterpret_cast(names[nindex])); }else{ strcpy(bptr, "(null)"); } bptr += strlen(bptr); s++; nindex++; } else { *bptr++ = *s; } } *bptr = '\0'; switch (flags) { case ERR_WARNING:error(bWARNING,buf); break; case ERR_FATAL: error(bDANGER, buf); throw Exception(""); case ERR_PANIC: error(bDANGER, buf); throw Exception(""); case ERR_INFO: error(bTRACE, buf); break; default: error(bDANGER, buf); break; } return 0; } void internalerror(char *message) {untested(); error(bDANGER, "internal error: %s\n", message); } #ifdef NGSPICE_17 int CKTinst2Node(void*, void*, int, CKTnode**, IFuid*) {untested();incomplete(); return 10; } #endif #ifdef JSPICE3 static IFfrontEnd fe = { NULL, //int ((*IFnewUid)()); /* create a new UID in the circuit */ noise, urcsetup NULL, //int ((*IFpauseTest)()); /* should we stop now? */ noisean.c only NULL, //double ((*IFseconds)()); /* what time is it? */ bjtdisto unused ifdef only (unused) IFerror, //int ((*IFerror)()); /* output an error or warning message */ temp, setup NULL, NULL, NULL, NULL, NULL }; #else static IFfrontEnd fe = { NULL, //int ((*IFnewUid)()); /* create a new UID in the circuit */ noise, urcsetup NULL, //int ((*IFdelUid)()); /* create a new UID in the circuit */ not used NULL, //int ((*IFpauseTest)()); /* should we stop now? */ noisean.c only NULL, //double ((*IFseconds)()); /* what time is it? */ bjtdisto unused ifdef only (unused) IFerror, //int ((*IFerror)()); /* output an error or warning message */ temp, setup NULL, //int ((*OUTpBeginPlot)()); /* start pointwise output plot */ noisean.c only NULL, //int ((*OUTpData)()); /* data for pointwise plot */ noisean.c only NULL, //int ((*OUTwBeginPlot)()); /* start windowed output plot */ not used NULL, //int ((*OUTwReference)()); /* independent vector for windowed plot */ not used NULL, //int ((*OUTwData)()); /* data for windowed plot */ not used NULL, //int ((*OUTwEnd)()); /* signal end of windows */ not used NULL, //int ((*OUTendPlot)()); /* end of plot */ not used NULL, //int ((*OUTbeginDomain)()); /* start nested domain */ not used NULL, //int ((*OUTendDomain)()); /* end nested domain */ not used NULL //int ((*OUTattributes)()); /* specify output attributes of node */ noisean.c only }; #endif IFfrontEnd* SPfrontEnd = &fe; //------------------------------------------------ //------------------------------------------------ int CKTsetBreak(CKTcircuit* ckt, double time) {untested(); if (time < ckt->CKTminBreak) {untested(); ckt->CKTminBreak = time; }else{untested(); } return OK; } //------------------------------------------------ void CKTterr(int qcap, CKTcircuit* ckt,double *time_step) { assert_ckt_localized(ckt); std::valarray q(OPT::_keep_time_steps); for (int ii = 0; ii < OPT::_keep_time_steps; ++ii) { assert(ckt->CKTstates[ii]); q[ii].x = NOT_VALID; q[ii].f0 = ckt->CKTstates[ii][qcap]; q[ii].f1 = NOT_VALID; } DEV_SPICE* d = reinterpret_cast(ckt->CKTstat); assert(d); assert(dynamic_cast(d)); *time_step = std::min(d->tr_review_trunc_error(&q[0]), *time_step); } //------------------------------------------------ int NIintegrate(CKTcircuit* ckt,double* geq,double* ceq,double cap,int qcap) { //-- used by DEVload (not DC) assert_ckt_localized(ckt); METHOD method; if (ckt->CKTorder == 1) { method = mEULER; }else{ assert(ckt->CKTtimePoints[1] != 0.); assert(ckt->CKTorder == 2); method = mTRAP; } std::valarray q(OPT::_keep_time_steps); std::valarray i(OPT::_keep_time_steps); for (int ii = 0; ii < OPT::_keep_time_steps; ++ii) { assert(ckt->CKTstates[ii]); q[ii].x = NOT_VALID; q[ii].f0 = ckt->CKTstates[ii][qcap]; q[ii].f1 = cap; trace3("", ii, q[ii].f0, q[ii].f1); i[ii].x = NOT_VALID; i[ii].f0 = ckt->CKTstates[ii][qcap+1]; i[ii].f1 = q[ii].f1 * ckt->CKTag[0]; trace3("", ii, i[ii].f0, i[ii].f1); assert(q[ii].f0 == q[ii].f0); assert(q[ii].f1 == q[ii].f1); assert(i[ii].f0 == i[ii].f0); assert(i[ii].f1 == i[ii].f1); } i[0] = differentiate(&q[0], &i[0], ckt->CKTtimePoints, method); assert(i[0].f0 == i[0].f0); assert(i[0].f1 == i[0].f1); trace2("", i[0].f0, i[0].f1); ckt->CKTstates[0][qcap+1] = i[0].f0; assert(ckt->CKTdelta != 0. || (ckt->CKTag[0] == 0. && i[0].f0 == 0.)); *ceq = i[0].f0 - q[0].f0 * ckt->CKTag[0]; *geq = i[0].f1; assert(*ceq == *ceq); assert(*geq == *geq); trace2("", *ceq, *geq); return OK; } //------------------------------------------------ //------------------------------------------------ int CKTmkVolt(CKTcircuit* ckt, CKTnode** n, IFuid, char*) { // get a new node number. -- used by DEVsetup assert_ckt_initialized(ckt); assert(n); static CKTnode n_static; // always used only on next line *n = &n_static; // so reuse static structure (*n)->number = ((ckt->CKTmaxEqNum)++)+OFFSET; trace1(__FUNCTION__, (*n)->number); // local number (- == internal) only number is used return OK; } int CKTmkCur(CKTcircuit* ckt, CKTnode** n, IFuid i, char* c) {untested(); return CKTmkVolt(ckt, n, i, c); } //------------------------------------------------ int CKTdltNNum(void*,int) {untested(); // complement to CKTmkVolt. -- used by DEVunsetup // deletes what was new in CKTmkVolt // Nothing, because of no alloc there. return OK; } //------------------------------------------------ //------------------------------------------------ double* SMPmakeElt(SMPmatrix* mm, int r, int c) { // returns a pointer m[r][c] -- used by DEVsetup //trace2("", r, c); assert(mm); if (r == 0 || c == 0) { static double trash; trash = 0; return &trash; }else{ assert(r >= 0+OFFSET); assert(r < MATRIX_NODES+OFFSET); assert(c >= 0+OFFSET); assert(c < MATRIX_NODES+OFFSET); COMPLEX** m = reinterpret_cast(mm); assert(m); assert(m[r-OFFSET]); return reinterpret_cast(&(m[r-OFFSET][c-OFFSET])); } } //------------------------------------------------ #ifdef JSPICE3 int IFnewUid(GENERIC*,IFuid*,IFuid,char*,int,GENERIC**) {incomplete(); return 0;} int INPpName(char*,IFvalue*,GENERIC*,int,GENERIC*) {incomplete(); return 0;} char *INPdevErr(char *) {incomplete(); return NULL;} char *INPerror(int) {incomplete(); return NULL;} spREAL *spGetElement(char* s, int r, int c) {return SMPmakeElt(s,r,c);} char *INPerrCat(char *, char *) {incomplete(); return NULL;} int INPgndInsert(GENERIC*,char**,INPtables*,GENERIC**) {incomplete(); return 0;} char * INPdevParse(char**,GENERIC*,int,GENERIC*,double*,int*,INPtables*) {incomplete(); return NULL;} char *INPgetMod(GENERIC*,char*,INPmodel**,INPtables*) {incomplete(); return NULL;} int INPgetTok(char**,char**,int) {incomplete(); return 0;} int INPlookMod(char*) {incomplete(); return 0;} int INPtermInsert(GENERIC*,char**,INPtables*,GENERIC**) {incomplete(); return 0;} int INPinsert(char**,INPtables*) {incomplete(); return 0;} char *copy(char*) {incomplete(); return NULL;} int NIsum(CKTcircuit*,double*,int) {incomplete(); return 0;} double INPevaluate(char**,int*,int) {incomplete(); return NOT_VALID;} IFvalue *INPgetValue(GENERIC*,char**,int,INPtables*) {incomplete(); return NULL;} #endif } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ // Verify that the layout of complex is as Spice assumes. // This is not guaranteed by the standard, but is believed to always be true. static struct COMPLEX_TEST { COMPLEX_TEST() { COMPLEX x; COMPLEX* px = &x; double* prx = &x.real(); double* pix = &x.imag(); assert(reinterpret_cast(prx) == reinterpret_cast(px)); assert(reinterpret_cast(pix-1) == reinterpret_cast(px)); } ~COMPLEX_TEST() { } } complex_test; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ int MODEL_SPICE::_count = -1; int DEV_SPICE::_count = -1; static DEV_SPICE p0; static DISPATCHER::INSTALL d0(&device_dispatcher, std::string(SPICE_LETTER) + "|" + DEVICE_TYPE, &p0); static MODEL_SPICE p1(&p0); static DISPATCHER::INSTALL d1(&model_dispatcher, MODEL_TYPE, &p1); /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/test_readline.cc��������������������������������������������������������������������������������0000664�0000000�0000000�00000000273�11454012162�0014774�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������//testing=trivial 2006.07.17 #include "md.h" #include #include int main() { char* line_read = readline("xx"); add_history(line_read); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/u_cardst.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000005556�11454012162�0013631�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_cardst.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * a structure to stash a "card" for fault. sweep, etc. */ //testing=script,complete 2006.07.14 #ifndef U_CARDST_H #define U_CARDST_H #include "e_compon.h" /*--------------------------------------------------------------------------*/ class CARDSTASH { private: COMPONENT* _brh; double _value; COMMON_COMPONENT* _c; public: explicit CARDSTASH() :_brh(0), _value(0.), _c(0) {} explicit CARDSTASH(CARD* b); CARDSTASH(const CARDSTASH& p); ~CARDSTASH() {COMMON_COMPONENT::detach_common(&_c);} void operator=(CARD* b); void restore() {assert(_brh); _brh->set_value(_value, _c);} #if 0 bool operator==(const CARDSTASH&)const {incomplete();unreachable();return false;} bool operator!=(const CARDSTASH&)const {incomplete();unreachable();return false;} bool operator<(const CARDSTASH&)const {incomplete();unreachable();return false;} bool operator>(const CARDSTASH&)const {incomplete();unreachable();return false;} // comparisons here because MS list requires them, even though not used here. #endif }; /*--------------------------------------------------------------------------*/ inline void CARDSTASH::operator=(CARD* b) { assert(b); _brh = prechecked_cast(b); assert(_brh); _value = _brh->value(); COMMON_COMPONENT::detach_common(&_c); COMMON_COMPONENT::attach_common(_brh->mutable_common(), &_c); } /*--------------------------------------------------------------------------*/ inline CARDSTASH::CARDSTASH(CARD* b) :_brh(0), _value(NOT_VALID), _c(0) { *this = b; } /*--------------------------------------------------------------------------*/ inline CARDSTASH::CARDSTASH(const CARDSTASH& p) :_brh(p._brh), _value(p._value), _c(0) { COMMON_COMPONENT::attach_common(p._c, &_c); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ��������������������������������������������������������������������������������������������������������������������������������������������������src/u_function.cc�����������������������������������������������������������������������������������0000664�0000000�0000000�00000002555�11454012162�0014330�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_function.cc,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2009 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ #include "e_base.h" #include "u_function.h" /*--------------------------------------------------------------------------*/ WAVE* FUNCTION::find_wave(const std::string& probe_name)const { return CKT_BASE::find_wave(probe_name); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ���������������������������������������������������������������������������������������������������������������������������������������������������src/u_function.h������������������������������������������������������������������������������������0000664�0000000�0000000�00000003003�11454012162�0014157�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_function.h,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2008 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ //testing=none #include "md.h" /*--------------------------------------------------------------------------*/ class CS; class CARD_LIST; class WAVE; /*--------------------------------------------------------------------------*/ class FUNCTION { public: virtual std::string eval(CS&, const CARD_LIST*)const = 0; protected: WAVE* find_wave(const std::string& probe_name)const; }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/u_lang.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000014560�11454012162�0013423�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_lang.cc,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2006 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include "c_comand.h" #include "d_dot.h" #include "d_coment.h" #include "d_subckt.h" #include "e_model.h" #include "u_lang.h" /*--------------------------------------------------------------------------*/ void LANGUAGE::parse_top_item(CS& cmd, CARD_LIST* Scope) { cmd.get_line(I_PROMPT); CMD::cmdproc(cmd, Scope); } /*--------------------------------------------------------------------------*/ const CARD* LANGUAGE::find_proto(const std::string& Name, const CARD* Scope) { const CARD* p = NULL; if (Scope) { try { p = Scope->find_looking_out(Name); }catch (Exception_Cant_Find& e) { assert(!p); } }else{ CARD_LIST::const_iterator i = CARD_LIST::card_list.find_(Name); if (i != CARD_LIST::card_list.end()) { p = *i; }else{ assert(!p); } } if (p) {itested(); return p; }else if ((p = command_dispatcher[Name])) { return new DEV_DOT; //BUG// memory leak }else if ((p = device_dispatcher[Name])) { return p; }else if ((p = model_dispatcher[Name])) { return p; }else{ assert(!p); std::string s; /* */if (Umatch(Name, "b{uild} ")) {itested(); s = "build";} else if (Umatch(Name, "del{ete} ")) { s = "delete";} else if (Umatch(Name, "fo{urier} ")) { s = "fourier";} else if (Umatch(Name, "gen{erator} ")) { s = "generator";} else if (Umatch(Name, "inc{lude} ")) {itested(); s = "include";} else if (Umatch(Name, "l{ist} ")) { s = "list";} else if (Umatch(Name, "m{odify} ")) { s = "modify";} else if (Umatch(Name, "opt{ions} ")) { s = "options";} else if (Umatch(Name, "par{ameter} ")) { s = "param";} else if (Umatch(Name, "pr{int} ")) { s = "print";} else if (Umatch(Name, "q{uit} ")) { s = "quit";} else if (Umatch(Name, "st{atus} ")) { s = "status";} else if (Umatch(Name, "te{mperature} ")){untested(); s = "temperature";} else if (Umatch(Name, "tr{ansient} ")) { s = "transient";} else if (Umatch(Name, "!")) {untested(); s = "system";} else if (Umatch(Name, "<")) {untested(); s = "<";} else if (Umatch(Name, ">")) {untested(); s = ">";} else{ /* no shortcut available */ s = Name; } if ((command_dispatcher[s])) { return new DEV_DOT; //BUG// we will look it up twice, //BUG// memory leak }else{ return NULL; } } } /*--------------------------------------------------------------------------*/ void LANGUAGE::new__instance(CS& cmd, MODEL_SUBCKT* owner, CARD_LIST* Scope) { if (cmd.is_end()) { // nothing }else{ std::string type = find_type_in_string(cmd); if (const CARD* proto = find_proto(type, owner)) { CARD* new_instance = proto->clone_instance(); assert(new_instance); new_instance->set_owner(owner); CARD* x = parse_item(cmd, new_instance); if (x) { assert(Scope); Scope->push_back(x); }else{ } }else{ cmd.warn(bDANGER, type + ": no match"); } } } /*--------------------------------------------------------------------------*/ CARD* LANGUAGE::parse_item(CS& cmd, CARD* c) { // See Stroustrup 15.4.5 // If you can think of a better way, tell me. // It must be in the LANGUAGE class, not CARD. if (dynamic_cast(c)) { return parse_module(cmd, prechecked_cast(c)); }else if (dynamic_cast(c)) { return parse_instance(cmd, prechecked_cast(c)); }else if (dynamic_cast(c)) { return parse_paramset(cmd, prechecked_cast(c)); }else if (dynamic_cast< DEV_COMMENT*>(c)) { return parse_comment(cmd, prechecked_cast(c)); }else if (dynamic_cast(c)) { return parse_command(cmd, prechecked_cast(c)); }else{untested(); incomplete(); unreachable(); return NULL; } } /*--------------------------------------------------------------------------*/ void LANGUAGE::print_item(OMSTREAM& o, const CARD* c) { // See Stroustrup 15.4.5 // If you can think of a better way, tell me. // It must be in the LANGUAGE class, not CARD. assert(c); assert(dynamic_cast(c)); if (dynamic_cast(c)) { print_module(o, prechecked_cast(c)); }else if (dynamic_cast(c)) { print_instance(o, prechecked_cast(c)); }else if (dynamic_cast(c)) { print_paramset(o, prechecked_cast(c)); }else if (dynamic_cast(c)) { print_comment(o, prechecked_cast(c)); }else if (dynamic_cast(c)) { print_command(o, prechecked_cast(c)); }else{untested(); incomplete(); unreachable(); } } /*--------------------------------------------------------------------------*/ OMSTREAM& operator<<(OMSTREAM& o, LANGUAGE* x) { if (x) { return (o << x->name()); }else{ return (o << "none"); } } /*--------------------------------------------------------------------------*/ bool Get(CS& cmd, const std::string& key, LANGUAGE** val) { if (cmd.umatch(key + " {=}")) { LANGUAGE* lang = language_dispatcher[cmd]; if (lang) { *val = lang; }else{ } return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ������������������������������������������������������������������������������������������������������������������������������������������������src/u_lang.h����������������������������������������������������������������������������������������0000664�0000000�0000000�00000006663�11454012162�0013272�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_lang.h,v 26.109 2009/02/02 06:39:10 al Exp $ -*- C++ -*- * Copyright (C) 2006 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #ifndef U_LANG_H #define U_LANG_H #include "u_opt.h" /*--------------------------------------------------------------------------*/ class COMPONENT; class MODEL_SUBCKT; class MODEL_CARD; class CARD; class DEV_COMMENT; class DEV_DOT; class CARD_LIST; /*--------------------------------------------------------------------------*/ class INTERFACE LANGUAGE { public: const CARD* find_proto(const std::string&, const CARD*); public: void new__instance(CS& cmd, MODEL_SUBCKT* owner, CARD_LIST* Scope); public: virtual ~LANGUAGE() {} virtual std::string name()const = 0; virtual bool case_insensitive()const = 0; virtual UNITS units()const = 0; public: // used by obsolete_callback virtual std::string arg_front()const = 0; virtual std::string arg_mid()const = 0; virtual std::string arg_back()const = 0; // in public: // real public interface virtual void parse_top_item(CS&, CARD_LIST*); virtual CARD* parse_item(CS&, CARD*); public: // called by commands and parse_item virtual DEV_COMMENT* parse_comment(CS&, DEV_COMMENT*) = 0; virtual DEV_DOT* parse_command(CS&, DEV_DOT*) = 0; virtual MODEL_CARD* parse_paramset(CS&, MODEL_CARD*) = 0; virtual MODEL_SUBCKT* parse_module(CS&, MODEL_SUBCKT*) = 0; virtual COMPONENT* parse_instance(CS&, COMPONENT*) = 0; virtual std::string find_type_in_string(CS&) = 0; // out public: // real public interface virtual void print_item(OMSTREAM&, const CARD*); private: // called by print_item virtual void print_paramset(OMSTREAM&, const MODEL_CARD*) = 0; virtual void print_module(OMSTREAM&, const MODEL_SUBCKT*) = 0; virtual void print_instance(OMSTREAM&, const COMPONENT*) = 0; virtual void print_comment(OMSTREAM&, const DEV_COMMENT*) = 0; virtual void print_command(OMSTREAM&, const DEV_DOT*) = 0; }; OMSTREAM& operator<<(OMSTREAM& o, LANGUAGE* x); bool Get(CS&, const std::string& key, LANGUAGE** val); /*--------------------------------------------------------------------------*/ // This is for backward compatibility only. // It will be removed in the future. // Do not use in new code. template void print_pair(OMSTREAM& o, LANGUAGE* lang, const std::string& name, T value, bool test=true) { if (test) { if (lang) { std::string front = lang->arg_front() + name + lang->arg_mid(); o << front << value << lang->arg_back(); }else{ o << ' ' + name + '=' << value; } }else{ } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif �����������������������������������������������������������������������������src/u_limit.h���������������������������������������������������������������������������������������0000664�0000000�0000000�00000007236�11454012162�0013464�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: u_limit.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2006 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * device limiting library */ //testing=script 2006.07.14 #ifndef U_LIMIT_H #define U_LIMIT_H #include "md.h" /*--------------------------------------------------------------------------*/ /* Spice style PN junction limiting */ inline double pnj_limit(double vnew, double vold, double vt, double vcrit) { trace4("limit-in", vnew, vold, vt, vcrit); if ((vnew > vcrit) && (std::abs(vnew - vold) > (2 * vt))) { if (vold > 0) { double arg = 1 + (vnew - vold) / vt; double vlim = (arg > 0) ? (vold + vt * log(arg)) : vcrit; trace3("limit-1", vlim, vt*log(arg), arg); return vlim; }else{ double vlim = vt * log(vnew/vt); trace3("limit-2", vlim, vt*log(vnew/vt), vnew/vt); return vlim; } }else{ trace1("limit-3", vnew); return vnew; } } /*--------------------------------------------------------------------------*/ inline double fet_limit_vds(double vnew, double vold) { if (vold >= 3.5) { if (vnew > (3*vold + 2)) {itested(); return 3 * vold + 2; }else if (vnew < 2) { return 2; }else{ return vnew; } }else{ if (vnew > 4) { return 4; }else if (vnew < -.5) { return -.5; }else{ return vnew; } } } /*--------------------------------------------------------------------------*/ inline double fet_limit_vgs(double vnew, double vold, double vto) { assert(vnew == vnew); assert(vold == vold); double vgst_old = vold - vto; double vgst_new = vnew - vto; double v_limited; if (vgst_old >= 3.5) { /* was strong on */ if (vgst_new < 2) { v_limited = 2; }else if (vgst_new > (3 * vgst_old + 2)) {itested(); v_limited = 3*vgst_old + 2; }else{ v_limited = vgst_new; } }else if (vgst_old >= 0) { /* middle region, on */ assert(vgst_old < 3.5); if (vgst_new < -.5) { v_limited = -.5; }else if (vgst_new > 4) { v_limited = 4; }else{ v_limited = vgst_new; } }else if (vgst_old <= 0) { /* was off, vgst_old < 0 */ assert(vgst_old < 0); if (vgst_new < (3 * vgst_old - 2)) { v_limited = 3*vgst_old - 2; }else if (vgst_new > .5) { v_limited = .5; }else{ v_limited = vgst_new; } }else{ /* overflow or other numeric error */ // not sure what to do in this case. // It could actually happen with overflow or divide by zero. // but supposedly this is trapped elsewhere. unreachable(); v_limited = 0.; trace3("huh?", vnew, vold, vto); trace3(" ", vgst_new, vgst_old, v_limited); } return v_limited + vto; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/u_nodemap.cc������������������������������������������������������������������������������������0000664�0000000�0000000�00000006442�11454012162�0014125�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_nodemap.cc,v 26.83 2008/06/05 04:46:59 al Exp $ -*- C++ -*- * Copyright (C) 2002 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * node name to number mapping -- for named nodes */ //testing=script,complete 2006.07.14 #include "e_node.h" #include "u_nodemap.h" /*--------------------------------------------------------------------------*/ NODE ground_node("0",0); /*--------------------------------------------------------------------------*/ NODE_MAP::NODE_MAP() : _node_map() { _node_map["0"] = &ground_node; } /*--------------------------------------------------------------------------*/ /* copy constructor: deep copy * The std::map copy constructor does a shallow copy, * then replace second with a deep copy. */ NODE_MAP::NODE_MAP(const NODE_MAP& p) : _node_map(p._node_map) { unreachable(); for (iterator i = _node_map.begin(); i != _node_map.end(); ++i) { untested(); if (i->first != "0") { untested(); assert(i->second); i->second = new NODE(i->second); }else{ untested(); } } } /*--------------------------------------------------------------------------*/ NODE_MAP::~NODE_MAP() { for (iterator i = _node_map.begin(); i != _node_map.end(); ++i) { if (i->first != "0") { assert(i->second); delete i->second; } } } /*--------------------------------------------------------------------------*/ /* return a pointer to a node given a string * returns NULL pointer if no match */ NODE* NODE_MAP::operator[](std::string s) { const_iterator i = _node_map.find(s); if (i != _node_map.end()) { return i->second; }else if (OPT::case_insensitive) { notstd::to_lower(&s); i = _node_map.find(s); }else{ return NULL; } return (i != _node_map.end()) ? i->second : NULL; } /*--------------------------------------------------------------------------*/ /* return a pointer to a node given a string * creates a new one if it isn't already there. */ NODE* NODE_MAP::new_node(std::string s) { if (OPT::case_insensitive) { notstd::to_lower(&s); }else{ } NODE* node = _node_map[s]; // increments how_many() when lookup fails (new s) if (!node) { node = new NODE(s, how_many()); // ^^^^ is really the map number of the new node _node_map[s] = node; } assert(node); return node; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/u_nodemap.h�������������������������������������������������������������������������������������0000664�0000000�0000000�00000003772�11454012162�0013772�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_nodemap.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2002 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * node name to number mapping -- for named nodes */ //testing=script,complete 2006.07.14 #ifndef U_NODEMAP_H #define U_NODEMAP_H #include "md.h" /*--------------------------------------------------------------------------*/ class NODE; /*--------------------------------------------------------------------------*/ class NODE_MAP { private: std::map _node_map; explicit NODE_MAP(const NODE_MAP&); public: explicit NODE_MAP(); ~NODE_MAP(); NODE* operator[](std::string); NODE* new_node(std::string); typedef std::map::iterator iterator; typedef std::map::const_iterator const_iterator; const_iterator begin()const {return _node_map.begin();} const_iterator end()const {return _node_map.end();} int how_many()const {return static_cast(_node_map.size()-1);} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ������src/u_opt.h�����������������������������������������������������������������������������������������0000664�0000000�0000000�00000022017�11454012162�0013142�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_opt.h,v 26.127 2009/11/09 16:06:11 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * all the options set by the .options card. */ //testing=script,complete 2006.07.14 #ifndef U_OPT_H #define U_OPT_H #include "mode.h" /*--------------------------------------------------------------------------*/ class CS; class LANGUAGE; /*--------------------------------------------------------------------------*/ /* integration method selector -- not all methods are implemented */ enum method_t {meUNKNOWN=0, // no method set meEULER, // backware Euler, unless forced to other meEULERONLY, // backward Euler only meTRAP, // usually trap, but euler where better meTRAPONLY, // always trapezoid meGEAR2, // usually gear2, but euler where better meGEAR2ONLY, // always gear2 (except breakpoints) meTRAPGEAR, // alt trap & gear2 meTRAPEULER, // alt trap & euler meNUM_METHODS}; // number of methods (array dimension) inline OMSTREAM& operator<<(OMSTREAM& o, method_t t) { const std::string s[] = {"unknown", "euler", "euleronly", "trap", "traponly", "gear2", "gear2only", "trapgear", "trapeuler"}; return (o << s[t]); } /*--------------------------------------------------------------------------*/ enum order_t {oREVERSE=1, oFORWARD, oAUTO}; inline OMSTREAM& operator<<(OMSTREAM& o, order_t t) { const std::string s[] = {"", "reverse", "forward", "auto"}; return (o << s[t]); } /*--------------------------------------------------------------------------*/ enum phase_t {pDEGREES, pRADIANS, pP_DEGREES, pN_DEGREES}; inline OMSTREAM& operator<<(OMSTREAM& o, phase_t t) { const std::string s[] = {"degrees", "radians", "+degrees", "-degrees"}; return (o << s[t]); } /*--------------------------------------------------------------------------*/ enum UNITS {uSI, uSPICE}; inline OMSTREAM& operator<<(OMSTREAM& o, UNITS t) { const std::string s[] = {"si", "spice"}; return (o << s[t]); } /*--------------------------------------------------------------------------*/ enum {dsINIT=001, dsRANGE=002, dsDEVLIMIT=004, dsDEVREGION=010, dsREVERSE=020}; /*--------------------------------------------------------------------------*/ class INTERFACE OPT { private: explicit OPT(const OPT&) {unreachable(); incomplete();} public: explicit OPT() {} ~OPT() {} void command(CS& cmd); private: bool set_values(CS& cmd); void print(OMSTREAM& where); public: enum ITL {DCBIAS=1, DCXFER=2, TRLOW=3, TRHIGH=4, TRTOTAL=5, SSTEP=6, WCASE=7, TRACE=8, ITL_COUNT=9}; enum {_keep_time_steps = 5}; public: static bool acct; // flag: print accounting info static bool listing; // flag: print listing static bool mod; // flag: print models static bool page; // flag: do page ejects static bool node; // flag: print node table static bool opts; // flag: print options static double gmin; // minimum conductance allowed static double bypasstol; // bypass tolerance multiplier static double loadtol; // trace load tolerance multiplier static double reltol; // relative error tolerance static double abstol; // absolute current error tolerance static double vntol; // absolute voltage error tolerance static double trtol; // transient error overestimation factor static double chgtol; // charge tolerance static double pivtol; // minimum acceptable pivot static double pivrel; // max to min ratio in a column? static int numdgt; // number of digits to display static double tnom_c; // nominal temperature static int cptime; // max allowed cpu time (seconds) static int limtim; // amt of time to reserve for plots static int limpts; // max points to print static int lvlcod; // enum: if == 2, solve fast static int lvltim; // enum: how to control time step static method_t method; // enum: integration method static int maxord; // max order of integration static double defl; // MOS default channel length static double defw; // MOS default channel width static double defad; // MOS default drain diffusion area static double defas; // MOS default source diffusion area static bool clobber; // allow to overwrite files without question static bool keys_between_nodes; // allow keywords between nodes static double floor; // display as zero if less than this static double vfloor; // display voltages as zero if less than this static double dampmax; // Newton-Raphson damping coefficient max static double dampmin; // Newton-Raphson damping coefficient min static int dampstrategy; // bit flags, damping strategy options static double roundofftol;// rel tolerance for zeroing after subtraction static double temp_c; // ambient temperature static double shortckt; // short resistance static int picky; // error picky-ness static unsigned outwidth; // width of output devices static double ydivisions; // plot divisions, y axis static phase_t phase; // how to print phase (degrees or radians) static order_t order; // ordering method static smode_t mode; // mixed-mode mode preference static int transits; // number of good transitions for digital static bool dupcheck; // check for duplicates on read static bool bypass; // bypass model evaluation, if appropriate static bool incmode; // make incremental changes to the matrix static bool lcbypass; // bypass L and C evaluation when appropriate static bool lubypass; // bypass parts of LU decomposition, if appropriate static bool fbbypass; // bypass fwd & back sub when last iter converged static bool traceload; // load only elements that need it, using queue static int itermin; // forced min iteration count. static double vmax; // + voltage limit for nonlinear calculations static double vmin; // - voltage limit for nonlinear calculations static double dtmin; // smallest internal step in transient analysis static double dtratio; // ratio of max / min dt in transient analysis static bool rstray; // include stray resistors in models static bool cstray; // include stray capacitors in models static int harmonics; // number of harmonics in fourier analysis static double trstepgrow; // limit of step size growth in transient analysis static double trstephold; // hold step size growth, converges slowly static double trstepshrink;// amt to shrink step size on convergence failure static double trreject; // how bad trunc error has to be to reject a step static int trsteporder; // interpolation order for step size control static double trstepcoef[_keep_time_steps]; // coefficient for step size control static bool showall; // flag: show development flags static int foooo; // a reusable value to aid development static int diodeflags; // convergence heuristic flags for diode static int mosflags; // convergence heuristic flags for mosfet static bool quitconvfail; // quit on convergence failure static bool edit; // use readline - command editing static int recursion; // max recursion depth static LANGUAGE* language; // simulation language static bool case_insensitive; static UNITS units; static double lowlim; // 1 - reltol static double uplim; // 1 + reltol static int itl[ITL_COUNT];// 1=dc (bias) iteration limit // 2=dc transfer iteration limit // 3=lower transient iteration limit // 4=upper transient iteration limit // 5=transient total iterations allowed // 6=source stepping iteration limit // 7=worst case iteration limit // 8=trace nonconvergence start iteration }; /*--------------------------------------------------------------------------*/ class SET_RUN_MODE { private: RUN_MODE _old_run_mode; explicit SET_RUN_MODE() :_old_run_mode(ENV::run_mode) {unreachable();} public: explicit SET_RUN_MODE(RUN_MODE rm) :_old_run_mode(ENV::run_mode) { ENV::run_mode = rm; } ~SET_RUN_MODE() { ENV::run_mode = _old_run_mode; } }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/u_opt1.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000007332�11454012162�0013364�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_opt1.cc,v 26.121 2009/09/22 20:30:18 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * all the options set by the .options card. * initialization and declaration of statics */ //testing=trivial 2006.07.17 #include "u_opt.h" bool OPT::acct = false; bool OPT::listing = false; bool OPT::mod = true; bool OPT::page = false; bool OPT::node = false; bool OPT::opts = false; double OPT::gmin = 1e-12; double OPT::bypasstol = .1; double OPT::loadtol = .1; double OPT::reltol = .001; double OPT::abstol = 1e-12; double OPT::vntol = 1e-6; double OPT::trtol = 7.0; double OPT::chgtol = 1e-14; double OPT::pivtol = 1e-13; double OPT::pivrel = 1e-3; int OPT::numdgt = 5; double OPT::tnom_c = 27.0; int OPT::cptime = 30000; int OPT::limtim = 2; int OPT::limpts = 201; int OPT::lvlcod = 2; int OPT::lvltim = 2; method_t OPT::method = meTRAP; int OPT::maxord = 2; double OPT::defl = 100e-6; double OPT::defw = 100e-6; double OPT::defad = 0.; double OPT::defas = 0.; bool OPT::clobber = true; bool OPT::keys_between_nodes = true; double OPT::dampmax = 1.0; double OPT::dampmin = 0.5; int OPT::dampstrategy = 0; //dsINIT|dsDEVREGION|dsREVERSE; double OPT::floor = 1e-21; double OPT::vfloor = 1e-15; double OPT::roundofftol = 1e-13; double OPT::temp_c = 27.0; double OPT::shortckt = 10e-6; int OPT::picky = bPICKY; unsigned OPT::outwidth = 9999; double OPT::ydivisions = 4.; phase_t OPT::phase = pDEGREES; order_t OPT::order = oAUTO; smode_t OPT::mode = moMIXED; int OPT::transits = 2; bool OPT::dupcheck = false; bool OPT::bypass = true; bool OPT::incmode = true; bool OPT::lcbypass = true; bool OPT::lubypass = true; bool OPT::fbbypass = true; bool OPT::traceload = true; int OPT::itermin = 1; double OPT::vmax = 5; double OPT::vmin = -5; double OPT::dtmin = 1e-12; double OPT::dtratio = 1e9; bool OPT::rstray = true; bool OPT::cstray = true; int OPT::harmonics = 9; double OPT::trstepgrow = 1e99; double OPT::trstephold = 1e99; double OPT::trstepshrink = 2.; /* spice is fixed at 8 */ double OPT::trreject = .5; int OPT::trsteporder = 3; double OPT::trstepcoef[_keep_time_steps] = {1., 1./4., 1./24., 1./192.}; bool OPT::showall = false; int OPT::foooo = 0; int OPT::diodeflags = 0; int OPT::mosflags = 0; bool OPT::quitconvfail = false; bool OPT::edit = true; int OPT::recursion = 20; LANGUAGE* OPT::language = NULL; bool OPT::case_insensitive = false; UNITS OPT::units = uSI; double OPT::lowlim = 1. - OPT::reltol; double OPT::uplim = 1. + OPT::reltol; int OPT::itl[OPT::ITL_COUNT] = { 100, /* 0=dummy */ 100, /* 1=dc (bias) iteration limit */ 50, /* 2=dc transfer iteration limit */ 6, /* 3=lower transient iteration limit (spice is 4) */ 20, /* 4=upper transient iteration limit (spice is 10) */ 0, /* 5=transient total iterations allowed */ 5000, /* 6=source stepping iteration limit */ 1, /* 7=worst case iteration limit */ 99 /* 8=trace nonconvergence start iteration */ }; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/u_opt2.cc���������������������������������������������������������������������������������������0000664�0000000�0000000�00000027022�11454012162�0013363�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_opt2.cc,v 26.132 2009/11/24 04:26:37 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * command and functions to access OPT class */ //testing=script,complete 2006.07.14 #include "u_lang.h" #include "l_compar.h" #include "ap.h" /*--------------------------------------------------------------------------*/ void OPT::command(CS& cmd) { bool changed = set_values(cmd); if (!changed || opts) { print(IO::mstdout); } } /*--------------------------------------------------------------------------*/ /* set: set options from a string */ bool OPT::set_values(CS& cmd) { bool big_change = false; bool changed = false; unsigned here = cmd.cursor(); do{ ONE_OF || Get(cmd, "acct", &acct) || Get(cmd, "list", &listing) || Get(cmd, "mod", &mod) || Get(cmd, "page", &page) || Get(cmd, "node", &node) || Get(cmd, "opts", &opts) || Get(cmd, "gmin", &gmin, mPOSITIVE) || Get(cmd, "bypasstol", &bypasstol, mPOSITIVE) || Get(cmd, "loadtol", &loadtol, mPOSITIVE) || Get(cmd, "reltol", &reltol, mPOSITIVE) || Get(cmd, "abstol", &abstol, mPOSITIVE) || Get(cmd, "vntol", &vntol, mPOSITIVE) || Get(cmd, "trtol", &trtol, mPOSITIVE) || Get(cmd, "chgtol", &chgtol, mPOSITIVE) || Get(cmd, "pivtol", &pivtol, mPOSITIVE) || Get(cmd, "pivrel", &pivrel, mPOSITIVE) || Get(cmd, "numdgt", &numdgt) || Get(cmd, "tnom", &tnom_c) || Get(cmd, "cptime", &cptime) || Get(cmd, "limtim", &limtim) || Get(cmd, "limpts", &limpts) || Get(cmd, "lvlcod", &lvlcod) || Get(cmd, "lvltim", &lvltim) || (cmd.umatch("method {=}") && (ONE_OF || Set(cmd, "euler", &method, meEULER) || Set(cmd, "eulero{nly}", &method, meEULERONLY) || Set(cmd, "trap{ezoidal}", &method, meTRAP) || Set(cmd, "trapo{nly}", &method, meTRAPONLY) || Set(cmd, "gear{2}", &method, meGEAR2) || Set(cmd, "gear2o{nly}", &method, meGEAR2ONLY) || Set(cmd, "t{rap}g{ear}", &method, meTRAPGEAR) || Set(cmd, "t{rap}e{uler}", &method, meTRAPEULER) || cmd.warn(bWARNING, "illegal method"))) || Get(cmd, "maxord", &maxord) || Get(cmd, "defl", &defl, mPOSITIVE) || Get(cmd, "defw", &defw, mPOSITIVE) || Get(cmd, "defad", &defad, mPOSITIVE) || Get(cmd, "defas", &defas, mPOSITIVE) || Get(cmd, "clobber", &clobber) || Get(cmd, "dampmax", &dampmax, mPOSITIVE) || Get(cmd, "dampmin", &dampmin, mPOSITIVE) || Get(cmd, "damps{trategy}",&dampstrategy, mOCTAL) || Get(cmd, "floor", &floor, mPOSITIVE) || Get(cmd, "vfloor", &vfloor, mPOSITIVE) || Get(cmd, "roundofftol", &roundofftol, mPOSITIVE) || Get(cmd, "t{empamb}", &temp_c) || Get(cmd, "t{emperature}", &temp_c) || Get(cmd, "short", &shortckt, mPOSITIVE) || Get(cmd, "out{width}", &outwidth) || Get(cmd, "ydiv{isions}", &ydivisions, mPOSITIVE) || Set(cmd, "nag", &picky, bNOERROR) || Set(cmd, "nonag", &picky, bTRACE) || Set(cmd, "trace", &picky, bTRACE) || Set(cmd, "notrace", &picky, bLOG) || Set(cmd, "log", &picky, bLOG) || Set(cmd, "nolog", &picky, bDEBUG) || Set(cmd, "debug", &picky, bDEBUG) || Set(cmd, "nodebug", &picky, bPICKY) || Set(cmd, "picky", &picky, bPICKY) || Set(cmd, "nopicky", &picky, bWARNING) || Set(cmd, "warn{ing}", &picky, bWARNING) || Set(cmd, "nowarn", &picky, bDANGER) || (cmd.umatch("phase {=}") && (ONE_OF || Set(cmd, "d{egrees}", &phase, pDEGREES) || Set(cmd, "+d{egrees}", &phase, pP_DEGREES) || Set(cmd, "-d{egrees}", &phase, pN_DEGREES) || Set(cmd, "r{adians}", &phase, pRADIANS) || cmd.warn(bWARNING, "need degrees or radians"))) || (cmd.umatch("order {=}") && (ONE_OF || Set(cmd, "r{everse}", &order, oREVERSE) || Set(cmd, "f{orward}", &order, oFORWARD) || Set(cmd, "a{uto}", &order, oAUTO) || cmd.warn(bWARNING, "need reverse, forward, or auto"))) || (cmd.umatch("mode {=}") && (ONE_OF || Set(cmd, "a{nalog}", &mode, moANALOG) || Set(cmd, "d{igital}", &mode, moDIGITAL) || Set(cmd, "m{ixed}", &mode, moMIXED) || cmd.warn(bWARNING, "need analog, digital, or mixed"))) || Get(cmd, "tr{ansits}", &transits) || Get(cmd, "dup{check}", &dupcheck) || Get(cmd, "byp{ass}", &bypass) || Get(cmd, "inc{mode}", &incmode) || Get(cmd, "lcb{ypass}", &lcbypass) || Get(cmd, "lub{ypass}", &lubypass) || Get(cmd, "fbb{ypass}", &fbbypass) || Get(cmd, "tracel{oad}", &traceload) || Get(cmd, "itermin", &itermin) || Get(cmd, "vmax", &vmax) || Get(cmd, "vmin", &vmin) || Get(cmd, "mrt", &dtmin, mPOSITIVE) || Get(cmd, "dtmin", &dtmin, mPOSITIVE) || Get(cmd, "dtr{atio}", &dtratio, mPOSITIVE) || (Get(cmd, "rstray", &rstray) && (big_change = true)) || (Get(cmd, "cstray", &cstray) && (big_change = true)) || Get(cmd, "harmonics", &harmonics) || Get(cmd, "trstepgrow", &trstepgrow, mPOSITIVE) || Get(cmd, "trstephold", &trstephold, mPOSITIVE) || Get(cmd, "trstepshrink", &trstepshrink,mPOSITIVE) || Get(cmd, "trreject", &trreject, mPOSITIVE) || Get(cmd, "trsteporder", &trsteporder) || Get(cmd, "trstepcoef1", &trstepcoef[1]) || Get(cmd, "trstepcoef2", &trstepcoef[2]) || Get(cmd, "trstepcoef3", &trstepcoef[3]) || Get(cmd, "showall", &showall) || Get(cmd, "foooo", &foooo) || Get(cmd, "diode{flags}", &diodeflags, mOCTAL) || Get(cmd, "mos{flags}", &mosflags, mOCTAL) || Get(cmd, "quitconv{fail}",&quitconvfail) || Get(cmd, "edit", &edit) || Get(cmd, "recur{sion}", &recursion) || (Get(cmd, "lang{uage}", &language) && ((case_insensitive = language->case_insensitive()), (units = language->units()), true)) || Get(cmd, "insensitive", &case_insensitive) || (cmd.umatch("units {=}") && (ONE_OF || Set(cmd, "si", &units, uSI) || Set(cmd, "spice", &units, uSPICE) || cmd.warn(bWARNING, "need si or spice"))) || Get(cmd, "itl1", &itl[1]) || Get(cmd, "itl2", &itl[2]) || Get(cmd, "itl3", &itl[3]) || Get(cmd, "itl4", &itl[4]) || Get(cmd, "itl5", &itl[5]) || Get(cmd, "itl6", &itl[6]) || Get(cmd, "itl7", &itl[7]) || Get(cmd, "itl8", &itl[8]) || (cmd.check(bWARNING, "what's this?"), cmd.skiparg()); if (!cmd.stuck(&here)) { changed = true; } }while (cmd.more() && changed); if (big_change) { //_sim->uninit(); //BUG// not sure if this is really working //regressions do go both ways, but not sure if it actually //makes the topology changes expected }else{ } if (changed) { lowlim = 1 - reltol; uplim = 1 + reltol; numdgt = to_range(3, numdgt, 20); } return changed; } /*--------------------------------------------------------------------------*/ /* print: "print" all option values to "o" * string is in a form suitable for passing to set */ void OPT::print(OMSTREAM& o) { o.setfloatwidth(7); o << "* i/o\n"; o << ".options"; o << ((acct) ?" acct" :" noacct"); o << ((listing)?" list" :" nolist"); o << ((clobber) ? " clobber" : " noclobber"); o << " out=" << outwidth; o << " ydivisions=" << ydivisions; o << " phase=" << phase; o << " harmonics=" << harmonics; o << ((edit) ?" edit" :" noedit"); o << " language=" << language; o << ((case_insensitive) ?" insensitive":" noinsensitive"); o << " units=" << units; o << " recursion="<< recursion; o << "\n\n"; o << "* accuracy, i/o\n"; o << ".options"; o << " numdgt=" << numdgt; o << " floor=" << floor; o << " vfloor=" << vfloor; o << " roundofftol=" << roundofftol; o << "\n\n"; o << "* accuracy, tolerances\n"; o << ".options"; o << " gmin=" << gmin; o << " short=" << shortckt; o << " reltol=" << reltol; o << " abstol=" << abstol; o << " vntol=" << vntol; o << " trtol=" << trtol; o << " chgtol=" << chgtol; o << " pivtol=" << pivtol; o << " bypasstol=" << bypasstol; o << " loadtol=" << loadtol; o << "\n\n"; o << "* accuracy, algorithms\n"; o << ".options"; o << " method=" << method; o << ((bypass) ?" bypass" :" nobypass"); o << ((incmode) ?" incmode" :" noincmode"); o << ((lcbypass) ?" lcbypass" :" nolcbypass"); o << ((lubypass) ?" lubypass" :" nolubypass"); o << ((fbbypass) ?" fbbypass" :" nofbbypass"); o << ((traceload)?" traceload":" notraceload"); o << " order=" << order; o << " mode=" << mode; o << " transits=" << transits; o << ((quitconvfail)?" quitconvfail":" noquitconvfail"); o << "\n\n"; o << "* iteration limiting and heuristics\n"; o << ".options"; for (int ii=1; ii> "real |integer "); // ignore type unsigned here = cmd.cursor(); for (;;) { if (!(cmd.more() && (cmd.is_alpha() || cmd.match1('_')))) { break; }else{ } std::string Name; PARAMETER Value; cmd >> Name >> '=' >> Value; if (cmd.stuck(&here)) {untested(); break; }else{ } if (OPT::case_insensitive) { notstd::to_lower(&Name); }else{ } _pl[Name] = Value; } cmd.check(bDANGER, "syntax error"); } /*--------------------------------------------------------------------------*/ void PARAM_LIST::print(OMSTREAM& o, LANGUAGE* lang)const { for (const_iterator i = _pl.begin(); i != _pl.end(); ++i) { if (i->second.has_hard_value()) { print_pair(o, lang, i->first, i->second); }else{ } } } /*--------------------------------------------------------------------------*/ bool PARAM_LIST::is_printable(int i)const { //BUG// ugly linear search int i_try = 0; for (const_iterator ii = _pl.begin(); ii != _pl.end(); ++ii) { if (i_try++ == i) { return ii->second.has_hard_value(); }else{ } } return false; } /*--------------------------------------------------------------------------*/ std::string PARAM_LIST::name(int i)const { //BUG// ugly linear search int i_try = 0; for (const_iterator ii = _pl.begin(); ii != _pl.end(); ++ii) { if (i_try++ == i) { return ii->first; }else{ } } return ""; } /*--------------------------------------------------------------------------*/ std::string PARAM_LIST::value(int i)const { //BUG// ugly linear search int i_try = 0; for (const_iterator ii = _pl.begin(); ii != _pl.end(); ++ii) { if (i_try++ == i) { return ii->second.string(); }else{ } } return ""; } /*--------------------------------------------------------------------------*/ void PARAM_LIST::eval_copy(PARAM_LIST& p, const CARD_LIST* scope) { assert(!_try_again); _try_again = p._try_again; for (iterator i = p._pl.begin(); i != p._pl.end(); ++i) { if (i->second.has_hard_value()) { if (_pl[i->first].has_hard_value()) {untested(); _pl[i->first] = i->second.e_val(_pl[i->first], scope); }else{ _pl[i->first] = i->second.e_val(NOT_INPUT, scope); } }else{ } } } /*--------------------------------------------------------------------------*/ const PARAMETER& PARAM_LIST::deep_lookup(std::string Name)const { if (OPT::case_insensitive) { notstd::to_lower(&Name); }else{ } PARAMETER & rv = _pl[Name]; if (rv.has_hard_value()) { // found a value, return it return rv; }else if (_try_again) { // didn't find one, look in enclosing scope return _try_again->deep_lookup(Name); }else{ // no enclosing scope to look in // really didn't find it, give up // return garbage value (NOT_INPUT) return rv; } } /*--------------------------------------------------------------------------*/ void PARAM_LIST::set(std::string Name, const std::string& Value) { if (OPT::case_insensitive) { notstd::to_lower(&Name); }else{ } _pl[Name] = Value; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ bool Get(CS& cmd, const std::string& key, PARAMETER* val) { if (cmd.umatch(key + ' ')) { if (cmd.skip1b('=')) { cmd >> *val; }else{ *val = true; } return true; }else if (cmd.umatch("no" + key)) { *val = false; return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ bool Get(CS& cmd, const std::string& key, PARAMETER* val) { if (cmd.umatch(key + " {=}")) { *val = int(cmd.ctof()); return true; }else{ return false; } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/u_parameter.h�����������������������������������������������������������������������������������0000664�0000000�0000000�00000023545�11454012162�0014327�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_parameter.h,v 26.125 2009/10/15 20:58:21 al Exp $ -*- C++ -*- * Copyright (C) 2005 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * A class for parameterized values * Used for spice compatible .param statements * and passing arguments to models and subcircuits */ //testing=script 2006.07.14 #ifndef U_PARAMETER_H #define U_PARAMETER_H #include "globals.h" #include "m_expression.h" #include "u_opt.h" #include "e_cardlist.h" /*--------------------------------------------------------------------------*/ class LANGUAGE; /*--------------------------------------------------------------------------*/ template class PARAMETER { private: mutable T _v; std::string _s; public: explicit PARAMETER() :_v(NOT_INPUT), _s() {} PARAMETER(const PARAMETER& p) :_v(p._v), _s(p._s) {} explicit PARAMETER(T v) :_v(v), _s() {} //explicit PARAMETER(T v, const std::string& s) :_v(v), _s(s) {untested();} ~PARAMETER() {} bool has_hard_value()const {return (_s != "");} bool has_good_value()const {return (_v != NOT_INPUT);} //bool has_soft_value()const {untested(); return (has_good_value() && !has_hard_value());} operator T()const {return _v;} T e_val(const T& def, const CARD_LIST* scope)const; void parse(CS& cmd); std::string string()const { if (_s == "#") { return to_string(_v); }else if (_s == "") { return "NA(" + to_string(_v) + ")"; }else{ return _s; } } void print(OMSTREAM& o)const {o << string();} void set_default(const T& v) {_v = v; _s = "";} void operator=(const PARAMETER& p) {_v = p._v; _s = p._s;} void operator=(const T& v) {_v = v; _s = "#";} //void operator=(const std::string& s) {untested();_s = s;} void operator=(const std::string& s) { if (strchr("'\"{", s[0])) { CS cmd(CS::_STRING, s); _s = cmd.ctos("", "'\"{", "'\"}"); }else if (s == "NA") { _s = ""; }else{ _s = s; } } bool operator==(const PARAMETER& p)const { return (_v == p._v && _s == p._s); } bool operator==(const T& v)const { if (v != NOT_INPUT) { return _v == v; }else{ return (_v == NOT_INPUT || !has_hard_value()); } } //bool operator!=(const PARAMETER& p)const {untested(); // return !(*this == p); //} //bool operator!=(const T& v)const {untested(); // return !(*this == v); //} T* pointer_hack() {return &_v;} private: T lookup_solve(const T& def, const CARD_LIST* scope)const; }; /*--------------------------------------------------------------------------*/ /* non-class interface, so non-paramaters can have same syntax */ /* It is needed by the model compiler */ #if 0 inline bool operator==(const PARAMETER& p, double v) {untested(); if (v != NOT_INPUT) {untested(); return p.operator==(static_cast(v)); }else{untested(); return (!(p.has_value())); } } #endif template bool has_hard_value(const PARAMETER& p) { return p.has_hard_value(); } #if 0 inline bool has_hard_value(double x) {untested(); return (x != NOT_INPUT); } inline bool has_good_value(double x) {untested(); return (x != NOT_INPUT); } #endif template bool has_good_value(const PARAMETER& p) { return p.has_good_value(); } #if 0 template bool has_soft_value(const PARAMETER& p) {untested(); return p.has_soft_value(); } #endif template bool has_nz_value(const T& p) { return (has_good_value(p) && p != 0); } template void set_default(PARAMETER* p, const T& v) { assert(p); p->set_default(v); } template void set_default(T* p, const T& v) { assert(p); *p = v; } template void e_val(PARAMETER* p, const PARAMETER& def, const CARD_LIST* scope) { assert(p); p->e_val(def, scope); } template void e_val(PARAMETER* p, const T& def, const CARD_LIST* scope) { assert(p); p->e_val(def, scope); } #if 0 template void e_val(T* p, const T& def, const CARD_LIST*) {untested(); assert(p); if (*p == NOT_INPUT) {untested(); *p = def; }else{untested(); } } #endif /*--------------------------------------------------------------------------*/ class INTERFACE PARAM_LIST { private: mutable std::map > _pl; public: PARAM_LIST* _try_again; // if you don't find it, also look here public: typedef std::map >::const_iterator const_iterator; typedef std::map >::iterator iterator; explicit PARAM_LIST() :_try_again(NULL) {} explicit PARAM_LIST(const PARAM_LIST& p) :_pl(p._pl), _try_again(p._try_again) {} //explicit PARAM_LIST(PARAM_LIST* ta) :_try_again(ta) {untested();} ~PARAM_LIST() {} void parse(CS& cmd); void print(OMSTREAM&, LANGUAGE*)const; size_t size()const {return _pl.size();} bool is_empty()const {return _pl.empty();} bool is_printable(int)const; std::string name(int)const; std::string value(int)const; void eval_copy(PARAM_LIST&, const CARD_LIST*); bool operator==(const PARAM_LIST& p)const {return _pl == p._pl;} const PARAMETER& deep_lookup(std::string)const; const PARAMETER& operator[](std::string i)const {return deep_lookup(i);} void set(std::string, const std::string&); void set_try_again(PARAM_LIST* t) {_try_again = t;} iterator begin() {return _pl.begin();} iterator end() {return _pl.end();} private: mutable int _index; mutable const_iterator _previous; }; /*--------------------------------------------------------------------------*/ template <> inline bool PARAMETER::lookup_solve(const bool&, const CARD_LIST*)const { CS cmd(CS::_STRING, _s); return cmd.ctob(); } /*--------------------------------------------------------------------------*/ template inline T PARAMETER::lookup_solve(const T& def, const CARD_LIST* scope)const { CS cmd(CS::_STRING, _s); Expression e(cmd); Expression reduced(e, scope); T v = T(reduced.eval()); if (v != NOT_INPUT) { return v; }else{ const PARAM_LIST* pl = scope->params(); return T(pl->deep_lookup(_s).e_val(def, scope)); } } /*--------------------------------------------------------------------------*/ #if 0 template inline T PARAMETER::lookup_solve(const T& def, const CARD_LIST* scope)const { const PARAM_LIST* pl = scope->params(); return T(pl->deep_lookup(_s).e_val(def, scope)); } #endif /*--------------------------------------------------------------------------*/ template T PARAMETER::e_val(const T& def, const CARD_LIST* scope)const { assert(scope); static int recursion=0; static const std::string* first_name = NULL; if (recursion == 0) { first_name = &_s; }else{ } assert(first_name); ++recursion; if (_s == "") { // blank string means to use default value _v = def; if (recursion > 1) { error(bWARNING, "parameter " + *first_name + " has no value\n"); }else{ } }else if (_s != "#") { // anything else means look up the value if (recursion <= OPT::recursion) { _v = lookup_solve(def, scope); if (_v == NOT_INPUT) {untested();itested(); error(bDANGER, "parameter " + *first_name + " has no value\n"); }else{ } }else{untested(); _v = def; error(bDANGER, "parameter " + *first_name + " recursion too deep\n"); } }else{ // start with # means we have a final value } --recursion; return _v; } /*--------------------------------------------------------------------------*/ template <> inline void PARAMETER::parse(CS& cmd) { bool new_val; cmd >> new_val; if (cmd) { _v = new_val; _s = "#"; }else{untested(); std::string name; //cmd >> name; name = cmd.ctos(",=();", "'{\"", "'}\""); if (cmd) {untested(); if (name == "NA") {untested(); _s = ""; }else{untested(); _s = name; } }else{untested(); } } if (!cmd) {untested(); _v = true; _s = "#"; }else{ } } /*--------------------------------------------------------------------------*/ template inline void PARAMETER::parse(CS& cmd) { T new_val; cmd >> new_val; if (cmd) { _v = new_val; _s = "#"; }else{ std::string name; //cmd >> name; name = cmd.ctos(",=();", "'{\"", "'}\""); if (cmd) { if (cmd.match1('(')) { _s = name + '(' + cmd.ctos("", "(", ")") + ')'; }else{ _s = name; } if (name == "NA") { _s = ""; }else{ } }else{ } } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ INTERFACE bool Get(CS& cmd, const std::string& key, PARAMETER* val); INTERFACE bool Get(CS& cmd, const std::string& key, PARAMETER* val); /*--------------------------------------------------------------------------*/ template inline OMSTREAM& operator<<(OMSTREAM& o, const PARAMETER p) { p.print(o); return o; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������src/u_prblst.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000021741�11454012162�0014007�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_prblst.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * probe list functions */ //testing=script,sparse 2006.07.14 #include "e_cardlist.h" #include "e_node.h" #include "e_card.h" #include "u_nodemap.h" #include "ap.h" #include "u_prblst.h" /*--------------------------------------------------------------------------*/ void PROBE_LISTS::purge(CKT_BASE* brh) { for (int i = 0; i < sCOUNT; ++i) { alarm[i].remove_one(brh); plot[i] .remove_one(brh); print[i].remove_one(brh); store[i].remove_one(brh); } } /*--------------------------------------------------------------------------*/ void PROBELIST::listing(const std::string& label)const { IO::mstdout.form("%-7s", label.c_str()); for (const_iterator p = begin(); p != end(); ++p) { IO::mstdout << ' ' << p->label(); if (p->range() != 0.) {untested(); IO::mstdout.setfloatwidth(5) << '(' << p->lo() << ',' << p->hi() << ')'; }else{ } } IO::mstdout << '\n'; } /*--------------------------------------------------------------------------*/ void PROBELIST::clear(void) { erase(begin(), end()); } /*--------------------------------------------------------------------------*/ /* check for match * called by STL remove, below * both are needed to support different versions of STL */ bool operator==(const PROBE& prb, const std::string& par) { return wmatch(prb.label(), par); } bool operator!=(const PROBE& prb, const std::string& par) {untested(); //return !wmatch(prb.label(), par); return !(prb == par); } /*--------------------------------------------------------------------------*/ /* remove a complete probe, extract from CS * wild card match ex: vds(m*) */ void PROBELIST::remove_list(CS& cmd) { unsigned mark = cmd.cursor(); std::string parameter(cmd.ctos(TOKENTERM) + '('); int paren = cmd.skip1b('('); parameter += cmd.ctos(TOKENTERM) + ')'; paren -= cmd.skip1b(')'); if (paren != 0) {untested(); cmd.warn(bWARNING, "need )"); }else if (parameter.empty()) {untested(); cmd.warn(bWARNING, "what's this?"); }else{ } iterator x = remove(begin(), end(), parameter); if (x != end()) { erase(x, end()); }else{itested(); cmd.warn(bWARNING, mark, "probe isn't set -- can't remove"); } } /*--------------------------------------------------------------------------*/ /* check for match * called by STL remove, below * both are needed to support different versions of stl */ bool operator==(const PROBE& prb, const CKT_BASE* brh) { return (prb.object() == brh); } bool operator!=(const PROBE& prb, const CKT_BASE* brh) {untested(); return (prb.object() != brh); } /*--------------------------------------------------------------------------*/ /* remove a brh from a PROBELIST * removes all probes on brh */ void PROBELIST::remove_one(CKT_BASE *brh) { assert(brh); erase(remove(begin(), end(), brh), end()); } /*--------------------------------------------------------------------------*/ /* add_list: add a "list" of probes, usually only one * This means possibly several probes with a single parameter * like "v(r*)" meaning all resistors * but not "v(r4) v(r5)" which has two parameters. * It also takes care of setting the range for plot or alarm. */ void PROBELIST::add_list(CS& cmd) { int oldcount = size(); std::string what(cmd.ctos(TOKENTERM));/* parameter */ if (what.empty()) {untested(); cmd.warn(bWARNING, "need a probe"); }else{ } int paren = cmd.skip1b('('); /* device, node, etc. */ if (cmd.umatch("nodes ")) { // all nodes add_all_nodes(what); }else if (cmd.umatch("0")) { // node 0 means system stuff push_new_probe(what, 0); }else if (cmd.is_alnum() || cmd.match1("*?")) { // branches or named nodes unsigned here1 = cmd.cursor(); bool found_something = add_branches(cmd.ctos(),what,&CARD_LIST::card_list); if (!found_something) { cmd.warn(bWARNING, here1, "no match"); }else{ } for (;;) { // a list, as in v(r1,r2,r3) or v(1,2,3) if (!(cmd.is_alnum() || cmd.match1("*?"))) { break; }else{ } unsigned here2 = cmd.cursor(); found_something = add_branches(cmd.ctos(),what,&CARD_LIST::card_list); if (!found_something) {itested(); cmd.reset(here2); break; }else{ } } }else{itested(); cmd.warn(bDANGER, "need device or node"); } paren -= cmd.skip1b(')'); if (paren != 0) {itested(); cmd.warn(bWARNING, "need )"); }else{ } if (cmd.skip1b('(')) { /* range for plotting and alarm */ double lo = cmd.ctof(); double hi = cmd.ctof(); for (iterator p = begin() + oldcount; p != end(); ++p) { p->set_limit(lo,hi); } if (!cmd.skip1b(')')) {untested(); cmd.check(bWARNING, "need )"); }else{ } }else{ } } /*--------------------------------------------------------------------------*/ void PROBELIST::push_new_probe(const std::string& param,const CKT_BASE* object) { bag.push_back(PROBE(param, object)); } /*--------------------------------------------------------------------------*/ void PROBELIST::add_all_nodes(const std::string& what) { for (NODE_MAP::const_iterator i = CARD_LIST::card_list.nodes()->begin(); i != CARD_LIST::card_list.nodes()->end(); ++i) { if ((i->first != "0") && (i->first.find('.') == std::string::npos)) { NODE* node = i->second; assert (node); push_new_probe(what, node); }else{ } } } /*--------------------------------------------------------------------------*/ /* add_branches: add net elements to probe list * all matching a label with wildcards */ bool PROBELIST::add_branches(const std::string&device, const std::string¶m, const CARD_LIST* scope) { assert(scope); bool found_something = false; std::string::size_type dotplace = device.find_first_of("."); if (dotplace != std::string::npos) { // has a dot, look deeper { // forward (Verilog style) std::string dev = device.substr(dotplace+1, std::string::npos); std::string container = device.substr(0, dotplace); for (CARD_LIST::const_iterator i = scope->begin(); i != scope->end(); ++i) { CARD* card = *i; if (card->is_device() && card->subckt() && wmatch(card->short_label(), container)) { found_something |= add_branches(dev, param, card->subckt()); }else{ } } } { // reverse (ACS style) dotplace = device.find_last_of("."); std::string container = device.substr(dotplace+1, std::string::npos); std::string dev = device.substr(0, dotplace); for (CARD_LIST::const_iterator i = scope->begin(); i != scope->end(); ++i) { CARD* card = *i; if (card->is_device() && card->subckt() && wmatch(card->short_label(), container)) { found_something |= add_branches(dev, param, card->subckt()); }else{ } } } }else{ // no dots, look here if (device.find_first_of("*?") != std::string::npos) { // there's a wild card. do linear search for all { // nodes for (NODE_MAP::const_iterator i = scope->nodes()->begin(); i != scope->nodes()->end(); ++i) { if (i->first != "0") { NODE* node = i->second; assert (node); if (wmatch(node->short_label(), device)) { push_new_probe(param, node); found_something = true; }else{ } }else{ } } } {// components for (CARD_LIST::const_iterator i = scope->begin(); i != scope->end(); ++i) { CARD* card = *i; if (wmatch(card->short_label(), device)) { push_new_probe(param, card); found_something = true; }else{ } } } }else{ // no wild card. do fast search for one { // nodes NODE* node = (*scope->nodes())[device]; if (node) { push_new_probe(param, node); found_something = true; }else{ } } { //components CARD_LIST::const_iterator i = scope->find_(device); if (i != scope->end()) { push_new_probe(param, *i); found_something = true; }else{ } } } } return found_something; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������src/u_prblst.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000005644�11454012162�0013655�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_prblst.h,v 26.136 2009/12/07 23:20:42 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * list of probes */ //testing=script,complete 2006.09.28 #ifndef U_PRBLST_H #define U_PRBLST_H #include "mode.h" #include "u_probe.h" /*--------------------------------------------------------------------------*/ class CARD_LIST; /*--------------------------------------------------------------------------*/ class INTERFACE PROBELIST { private: typedef std::vector _container; _container bag; explicit PROBELIST(const PROBELIST&) {unreachable();incomplete();} public: explicit PROBELIST() {} ~PROBELIST() {} typedef _container::iterator iterator; typedef _container::const_iterator const_iterator; void listing(const std::string&)const; void clear(); void remove_list(CS&); void remove_one(CKT_BASE*); void add_list(CS&); int size()const {return static_cast(bag.size());} const_iterator begin()const {return bag.begin();} const_iterator end()const {return bag.end();} iterator begin() {return bag.begin();} iterator end() {return bag.end();} virtual void open(CS&) {incomplete();} virtual void send(OMSTREAM, double) {incomplete();} virtual void close() {incomplete();} private: void erase(iterator b, iterator e) {bag.erase(b,e);} void push_new_probe(const std::string& param, const CKT_BASE* object); bool add_branches(const std::string&,const std::string&,const CARD_LIST*); void add_all_nodes(const std::string&); }; /*--------------------------------------------------------------------------*/ class INTERFACE PROBE_LISTS { public: static PROBELIST alarm[sCOUNT]; // list of alarm probes static PROBELIST plot[sCOUNT]; // list of plot probes static PROBELIST print[sCOUNT]; // list of print probes static PROBELIST store[sCOUNT]; // list of probes to store for postproc static void purge(CKT_BASE*); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ��������������������������������������������������������������������������������������������src/u_probe.cc��������������������������������������������������������������������������������������0000664�0000000�0000000�00000010067�11454012162�0013607�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_probe.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * general probe object */ //testing=script 2009.06.21 #include "u_sim_data.h" #include "u_status.h" #include "e_base.h" #include "u_probe.h" /*--------------------------------------------------------------------------*/ PROBE::PROBE(const std::string& what,const CKT_BASE *brh) :_what(what), _brh(brh), _lo(0.), _hi(0.) { if (_brh) { _brh->inc_probes(); }else{ } } /*--------------------------------------------------------------------------*/ PROBE::PROBE(const PROBE& p) :_what(p._what), _brh(p._brh), _lo(p._lo), _hi(p._hi) { if (_brh) { _brh->inc_probes(); }else{ } } /*--------------------------------------------------------------------------*/ /* operator= ... assignment * copy a probe */ PROBE& PROBE::operator=(const PROBE& p) { detach(); _what = p._what; _brh = p._brh; _lo = p._lo; _hi = p._hi; if (_brh) { _brh->inc_probes(); }else{untested(); } return *this; } /*--------------------------------------------------------------------------*/ /* "detach" a probe from a device * which means ... 1. tell the device that the probe has been removed * 2. blank out the probe, so it doesn't reference anything * does not remove the probe from the list */ void PROBE::detach() { if (_brh) { _brh->dec_probes(); }else{ } _what = ""; _brh = 0; } /*--------------------------------------------------------------------------*/ /* label: returns a string corresponding to a possible probe point * (suitable for printing) * It has nothing to do with whether it was selected or not */ const std::string PROBE::label(void)const { if (_brh) { return _what + '(' + _brh->long_label() + ')'; }else{ return _what + "(0)"; } } /*--------------------------------------------------------------------------*/ double PROBE::value(void)const { // _brh is either a node or a "branch", which is really any device if (_brh) { return _brh->probe_num(_what); }else{ return probe_node(); } } /*--------------------------------------------------------------------------*/ double PROBE::probe_node(void)const { if (Umatch(_what, "iter ")) { assert(iPRINTSTEP - sCOUNT == 0); assert(iSTEP - sCOUNT == 1); assert(iTOTAL - sCOUNT == 2); assert(iCOUNT - sCOUNT == 3); return CKT_BASE::_sim->_iter[sCOUNT]; }else if (Umatch(_what, "bypass ")) {untested(); return OPT::bypass + 10*CKT_BASE::_sim->_bypass_ok; }else if (Umatch(_what, "control ")) { return ::status.control; }else if (Umatch(_what, "damp ")) {untested(); return CKT_BASE::_sim->_damp; }else if (Umatch(_what, "gen{erator} ")) {untested(); return CKT_BASE::_sim->_genout; }else if (Umatch(_what, "hidden ")) {untested(); return ::status.hidden_steps; }else if (Umatch(_what, "temp{erature} ")) {untested(); return CKT_BASE::_sim->_temp_c; }else if (Umatch(_what, "time ")) {untested(); return CKT_BASE::_sim->_time0; }else{ return NOT_VALID; } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/u_probe.h���������������������������������������������������������������������������������������0000664�0000000�0000000�00000004142�11454012162�0013446�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_probe.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * single probe item */ //testing=script,complete 2006.07.14 #ifndef U_PROBE_H #define U_PROBE_H #include "l_compar.h" // inorder /*--------------------------------------------------------------------------*/ class CKT_BASE; /*--------------------------------------------------------------------------*/ class INTERFACE PROBE { private: std::string _what; const CKT_BASE* _brh; double _lo,_hi; public: explicit PROBE(const std::string& what, const CKT_BASE *brh); PROBE(const PROBE& p); ~PROBE() {detach();} void set_limit(double Lo,double Hi) {_lo = Lo; _hi = Hi;} void detach(); PROBE& operator=(const PROBE& p); const std::string label()const; double value()const; const CKT_BASE* object()const {return _brh;} double lo()const {return _lo;} double hi()const {return _hi;} double range()const {return hi()-lo();} bool in_range()const{return in_order(lo(),value(),hi());} private: double probe_node()const; }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/u_sdp.h�����������������������������������������������������������������������������������������0000664�0000000�0000000�00000006541�11454012162�0013132�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_sdp.h,v 26.83 2008/06/05 04:46:59 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * A class for Size Dependent Parameters, like those used in Spice BSIM models * A single read gets the nominal, and length and width dependencies. * A single print prints them all. * operator() returns the value to use, adjusted for L and W. */ //testing=script 2006.07.14 #ifndef U_SDP_H #define U_SDP_H #include "u_parameter.h" /*--------------------------------------------------------------------------*/ class OMSTREAM; class CARD_LIST; /*--------------------------------------------------------------------------*/ class SDP { //friend bool get(CS& cmd, const std::string& key, SDP* value); private: PARAMETER _nom; // nominal value PARAMETER _ld; // length dependency PARAMETER _wd; // width dependency PARAMETER _pd; // cross-term dependency (p is for product) explicit SDP() {unreachable();} public: explicit SDP(const SDP& p) :_nom(p._nom),_ld(p._ld),_wd(p._wd),_pd(p._pd) {} ~SDP() {} explicit SDP(double Nom) :_nom(Nom), _ld(0.), _wd(0.), _pd(0.) {} //void print(OMSTREAM& o, LANGUAGE*, const std::string& name)const; double operator()(double L,double W,double def,const CARD_LIST* scope)const { return _nom.e_val(def,scope) + _ld.e_val(0.,scope)/L + _wd.e_val(0.,scope)/W + _pd.e_val(0.,scope)/(W*L); } double nom()const {return _nom;} void set_nom(double n) {untested();_nom = n;} void set_w(double n) {untested();_wd = n;} void set_l(double n) {untested();_ld = n;} void set_p(double n) {untested();_pd = n;} void set_nom(const std::string& n) {_nom = n;} void set_w(const std::string& n) {_wd = n;} void set_l(const std::string& n) {_ld = n;} void set_p(const std::string& n) {itested();_pd = n;} bool has_hard_value()const {return _nom.has_hard_value();} bool has_good_value()const {return _nom.has_good_value();} bool has_value()const {return _nom.has_hard_value();} bool w_has_value()const {return _wd.has_hard_value();} bool l_has_value()const {return _ld.has_hard_value();} bool p_has_value()const {return _pd.has_hard_value();} std::string string()const {return _nom.string();} std::string w_string()const {return _wd.string();} std::string l_string()const {return _ld.string();} std::string p_string()const {return _pd.string();} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������src/u_sim_data.cc�����������������������������������������������������������������������������������0000664�0000000�0000000�00000016725�11454012162�0014270�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_sim_data.cc,v 26.135 2009/12/02 09:26:53 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * aux functions associated with the SIM class */ //testing=obsolete #include "e_node.h" #include "u_nodemap.h" #include "e_cardlist.h" #include "u_status.h" /*--------------------------------------------------------------------------*/ void SIM_DATA::set_limit() { for (int ii = 1; ii <= _total_nodes; ++ii) { set_limit(_v0[ii]); } } /*--------------------------------------------------------------------------*/ void SIM_DATA::set_limit(double v) { if (v+.4 > _vmax) { _vmax = v+.5; error(bTRACE, "new max = %g, new limit = %g\n", v, _vmax); } if (v-.4 < _vmin) { _vmin = v-.5; error(bTRACE, "new min = %g, new limit = %g\n", v, _vmin); } } /*--------------------------------------------------------------------------*/ void SIM_DATA::clear_limit() { _vmax = OPT::vmax; _vmin = OPT::vmin; } /*--------------------------------------------------------------------------*/ void SIM_DATA::keep_voltages() { if (!_freezetime) { for (int ii = 1; ii <= _total_nodes; ++ii) { _vdc[ii] = _v0[ii]; } _last_time = (_time0 > 0.) ? _time0 : 0.; }else{untested(); } } /*--------------------------------------------------------------------------*/ void SIM_DATA::restore_voltages() { for (int ii = 1; ii <= _total_nodes; ++ii) { _vt1[ii] = _v0[ii] = _vdc[ii]; } } /*--------------------------------------------------------------------------*/ void SIM_DATA::zero_voltages() { for (int ii = 1; ii <= _total_nodes; ++ii) { _vt1[ii] = _v0[ii] = _vdc[ii] = _i[ii] = 0.; } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* map__nodes: map intermediate node number to internal node number. * Ideally, this function would find some near-optimal order * and squash out gaps. */ void SIM_DATA::map__nodes() { _nm = new int[_total_nodes+1]; ::status.order.reset().start(); switch (OPT::order) { default: untested(); error(bWARNING, "invalid order spec: %d\n", OPT::order); case oAUTO: order_auto(); break; case oREVERSE: untested(); order_reverse(); break; case oFORWARD: untested(); order_forward(); break; } ::status.order.stop(); } /*--------------------------------------------------------------------------*/ /* order_reverse: force ordering to reverse of user ordering * subcircuits at beginning, results on border at the bottom */ void SIM_DATA::order_reverse() {untested(); _nm[0] = 0; for (int node = 1; node <= _total_nodes; ++node) {untested(); _nm[node] = _total_nodes - node + 1; } } /*--------------------------------------------------------------------------*/ /* order_forward: use user ordering, with subcircuits added to end * results in border at the top (worst possible if lots of subcircuits) */ void SIM_DATA::order_forward() {untested(); _nm[0] = 0; for (int node = 1; node <= _total_nodes; ++node) {untested(); _nm[node] = node; } } /*--------------------------------------------------------------------------*/ /* order_auto: full automatic ordering * reverse, for now */ void SIM_DATA::order_auto() { _nm[0] = 0; for (int node = 1; node <= _total_nodes; ++node) { _nm[node] = _total_nodes - node + 1; } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* init: allocate, set up, etc ... for any type of simulation * also called by status and probe for access to internals and subckts */ void SIM_DATA::init() { if (is_first_expand()) { uninit(); init_node_count(CARD_LIST::card_list.nodes()->how_many(), 0, 0); CARD_LIST::card_list.expand(); CARD_LIST::card_list.precalc_last(); map__nodes(); CARD_LIST::card_list.map_nodes(); alloc_hold_vectors(); _aa.reinit(_total_nodes); _lu.reinit(_total_nodes); _acx.reinit(_total_nodes); CARD_LIST::card_list.tr_iwant_matrix(); CARD_LIST::card_list.ac_iwant_matrix(); _last_time = 0; }else{ CARD_LIST::card_list.precalc_first(); CARD_LIST::card_list.precalc_last(); } } /*--------------------------------------------------------------------------*/ /* alloc_hold_vectors: * allocate space to hold data between commands. * for restart, convergence assistance, bias for AC, post-processing, etc. * must be done BEFORE deciding what array elements to allocate, * but after mapping * if they already exist, leave them alone to save data */ void SIM_DATA::alloc_hold_vectors() { assert(is_first_expand()); assert(!_nstat); _nstat = new LOGIC_NODE[_total_nodes+1]; for (int ii=0; ii <= _total_nodes; ++ii) { _nstat[_nm[ii]].set_user_number(ii); } assert(!_vdc); _vdc = new double[_total_nodes+1]; std::fill_n(_vdc, _total_nodes+1, 0); assert(_nstat); assert(_vdc); } /*--------------------------------------------------------------------------*/ /* alloc_vectors: * these are new with every run and are discarded after the run. */ void SIM_DATA::alloc_vectors() { assert(_evalq1.empty()); assert(_evalq2.empty()); assert(_evalq != _evalq_uc); assert(!_ac); assert(!_i); assert(!_v0); assert(!_vt1); _ac = new COMPLEX[_total_nodes+1]; _i = new double[_total_nodes+1]; _v0 = new double[_total_nodes+1]; _vt1 = new double[_total_nodes+1]; std::fill_n(_ac, _total_nodes+1, 0); std::fill_n(_i, _total_nodes+1, 0); std::fill_n(_v0, _total_nodes+1, 0); std::fill_n(_vt1,_total_nodes+1, 0); } /*--------------------------------------------------------------------------*/ void SIM_DATA::unalloc_vectors() { _evalq1.clear(); _evalq2.clear(); delete [] _i; _i = NULL; delete [] _v0; _v0 = NULL; delete [] _vt1; _vt1 = NULL; delete [] _ac; _ac = NULL; } /*--------------------------------------------------------------------------*/ /* uninit: undo all the allocation associated with any simulation * called when the circuit changes after a run, so it needs a restart * may be called multiple times without damage to make sure it is clean */ void SIM_DATA::uninit() { if (_vdc) { _acx.reinit(0); _lu.reinit(0); _aa.reinit(0); delete [] _vdc; _vdc = NULL; delete [] _nstat; _nstat = NULL; delete [] _nm; _nm = NULL; }else{ assert(_acx.size() == 0); assert(_lu.size() == 0); assert(_aa.size() == 0); assert(!_nstat); assert(!_nm); } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ �������������������������������������������src/u_sim_data.h������������������������������������������������������������������������������������0000664�0000000�0000000�00000016207�11454012162�0014125�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_sim_data.h,v 26.133 2009/11/26 05:02:28 al Exp $ -*- C++ -*- * Copyright (C) 2009 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * real base for anything to do with a circuit */ //testing=obsolete #ifndef U_SIM_DATA_H #define U_SIM_DATA_H #include "constant.h" #include "l_compar.h" #include "u_opt.h" #include "m_matrix.h" /*--------------------------------------------------------------------------*/ // external class WAVE; class CARD; class LOGIC_NODE; /*--------------------------------------------------------------------------*/ enum TRI_STATE {tsNO=0, tsYES=1, tsBAD=-1}; /*--------------------------------------------------------------------------*/ struct INTERFACE SIM_DATA { double _time0; /* time now */ double _freq; /* AC frequency to analyze at (Hertz) */ double _temp_c; /* ambient temperature, actual */ double _damp; /* Newton-Raphson damping coefficient actual */ double _dtmin; /* min internal step size */ double _genout; /* tr dc input to circuit (generator) */ bool _bypass_ok; /* flag: ok to bypass model evaluation */ bool _fulldamp; /* flag: big iter. jump. use full (min) damp */ double _last_time; /* time at which "volts" is valid */ bool _freezetime; /* flag: don't advance stored time */ int _iter[iCOUNT]; int _user_nodes; int _subckt_nodes; int _model_nodes; int _total_nodes; COMPLEX _jomega; /* AC frequency to analyze at (radians) */ bool _limiting; /* flag: node limiting */ double _vmax; double _vmin; bool _uic; /* flag: use initial conditions (spice-like) */ TRI_STATE _inc_mode; /* flag: make incremental changes (3 state) */ SIM_MODE _mode; /* simulation type (AC, DC, ...) */ SIM_PHASE _phase; /* phase of simulation (iter, init-dc,) */ int *_nm; /* node map (external to internal) */ double *_i; /* dc-tran current (i) vector */ double *_v0; /* dc-tran voltage, new */ double *_vt1; /* dc-tran voltage, 1 time ago */ /* used to restore after rejected step */ COMPLEX *_ac; /* ac right side */ LOGIC_NODE* _nstat; /* digital data */ double *_vdc; /* saved dc voltages */ BSMATRIX _aa; /* raw matrix for DC & tran */ BSMATRIX _lu; /* decomposed matrix for DC & tran */ BSMATRIX _acx;/* raw & decomposed matrix for AC */ std::priority_queue > _eq; /*event queue*/ std::vector _loadq; std::vector _acceptq; std::deque _evalq1; /* evaluate queues -- alternate between */ std::deque _evalq2; /* build one while other is processed */ std::deque _late_evalq; /* eval after everything else */ std::deque* _evalq; /* pointer to evalq to process */ std::deque* _evalq_uc;/* pointer to evalq under construction */ WAVE *_waves; /* storage for waveforms "store" command*/ SIM_DATA() { _evalq = &_evalq1; _evalq_uc = &_evalq2; } bool is_first_expand() {return !_nstat;} void alloc_hold_vectors(); /* s__init.cc */ void alloc_vectors(); void unalloc_vectors(); void init(); void uninit(); void set_limit(); /* s__aux.cc */ void set_limit(double v); void clear_limit(); void keep_voltages(); void restore_voltages(); void zero_voltages(); void map__nodes(); /* s__map.cc */ void order_reverse(); void order_forward(); void order_auto(); int init_node_count(int user, int sub, int mod) { _user_nodes=user; _subckt_nodes=sub; _model_nodes=mod; return (_total_nodes=user+sub+mod); } int newnode_subckt() {++_subckt_nodes; return ++_total_nodes;} int newnode_model() {++_model_nodes; return ++_total_nodes;} bool is_inc_mode() {return _inc_mode;} bool inc_mode_is_no() {return _inc_mode == tsNO;} bool inc_mode_is_bad() {return _inc_mode == tsBAD;} void set_inc_mode_bad() {_inc_mode = tsBAD;} void set_inc_mode_yes() {_inc_mode = tsYES;} void set_inc_mode_no() {_inc_mode = tsNO;} void mark_inc_mode_bad() { switch (_inc_mode) { case tsYES: _inc_mode = tsBAD; break; case tsBAD: break; case tsNO: break; } } void new_event(double etime) { if (etime <= BIGBIG) { _eq.push(etime); }else{ } } void set_command_none() {_mode = s_NONE;} void set_command_ac() {_mode = s_AC;} void set_command_dc() {_mode = s_DC;} void set_command_op() {_mode = s_OP;} void set_command_tran() {_mode = s_TRAN;} void set_command_fourier() {_mode = s_FOURIER;} SIM_MODE sim_mode() {return _mode;} bool command_is_ac() {return _mode == s_AC;} bool command_is_dc() {return _mode == s_DC;} bool command_is_op() {return _mode == s_OP;} //bool command_is_tran() {return _mode == s_TRAN;} //bool command_is_fourier() {return _mode == s_FOURIER;} bool analysis_is_ac() {return _mode == s_AC;} bool analysis_is_dcop() {return _mode == s_DC || _mode == s_OP;} bool analysis_is_static() {return _phase == p_INIT_DC || _phase == p_DC_SWEEP;} bool analysis_is_restore() {return _phase == p_RESTORE;} bool analysis_is_tran() {return _mode == s_TRAN || _mode == s_FOURIER;} bool analysis_is_tran_static() {return analysis_is_tran() && _phase == p_INIT_DC;} bool analysis_is_tran_restore() {return analysis_is_tran() && _phase == p_RESTORE;} bool analysis_is_tran_dynamic() {return analysis_is_tran() && _phase == p_TRAN;} void reset_iteration_counter(int i) {assert(up_order(0,i,iCOUNT-1)); _iter[i] = 0;} void count_iterations(int i) {assert(up_order(0,i,iCOUNT-1)); ++_iter[i];} int iteration_tag()const {return _iter[iTOTAL];} int iteration_number()const {return _iter[iSTEP];} bool is_initial_step() {return (_iter[_mode] <= 1 && analysis_is_static());} bool is_advance_iteration()const {return (_iter[iSTEP] == 0);} bool is_advance_or_first_iteration()const {assert(_iter[iSTEP]>=0); return (_iter[iSTEP]<=1);} bool is_first_iteration()const {assert(_iter[iSTEP] > 0); return (_iter[iSTEP] == 1);} bool is_second_iteration()const {assert(_iter[iSTEP] > 0); return (_iter[iSTEP] == 2);} bool is_iteration_number(int n)const {return (_iter[iSTEP] == n);} bool exceeds_iteration_limit(OPT::ITL itlnum)const {return(_iter[iSTEP] > OPT::itl[itlnum]);} bool uic_now() {return _uic && analysis_is_static() && _time0==0.;} }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/u_status.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000005255�11454012162�0013670�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_status.h,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * place to store all kinds of statistics */ //testing=script 2006.07.14 #ifndef STATUS_H #define STATUS_H #include "mode.h" #include "l_timer.h" /*--------------------------------------------------------------------------*/ class CS; /*--------------------------------------------------------------------------*/ class STATUS { public: void command(CS& cmd); public: TIMER get; TIMER op; TIMER dc; TIMER tran; TIMER four; TIMER ac; TIMER set_up; TIMER order; TIMER advance; TIMER queue; TIMER evaluate; TIMER load; TIMER lud; TIMER back; TIMER review; TIMER accept; TIMER output; mutable TIMER overhead; TIMER aux1; TIMER aux2; TIMER aux3; TIMER total; int control; int hidden_steps; void compute_overhead()const { overhead = total - advance - queue - evaluate - load - lud - back - output - review - accept; } explicit STATUS() : get("get"), op("op"), dc("dc"), tran("tran"), four("fourier"), ac("ac"), set_up("setup"), order("order"), advance("advance"), queue("queue"), evaluate("evaluate"), load("load"), lud("lu"), back("back"), review("review"), accept("accept"), output("output"), overhead("overhead"), aux1("aux1"), aux2("aux2"), aux3("aux3"), total("total"), control(0), hidden_steps(0) { } ~STATUS() {} private: explicit STATUS(const STATUS&) {unreachable(); incomplete();} }; /*--------------------------------------------------------------------------*/ extern INTERFACE STATUS status; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/u_time_pair.h�����������������������������������������������������������������������������������0000664�0000000�0000000�00000004550�11454012162�0014313�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_time_pair.h,v 26.81 2008/05/27 05:34:00 al Exp $ -*- C++ -*- * Copyright (C) 2008 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ //testing=script 2008.05.09 #ifndef U_TIME_PAIR_H_INCLUDED #define U_TIME_PAIR_H_INCLUDED #include "constant.h" /*--------------------------------------------------------------------------*/ struct TIME_PAIR { double _error_estimate; double _event; TIME_PAIR() : _error_estimate(NEVER), _event(NEVER) {} TIME_PAIR(double Error, double Event) : _error_estimate(Error), _event(Event) {} TIME_PAIR(const TIME_PAIR& P) : _error_estimate(P._error_estimate), _event(P._event) {} TIME_PAIR& reset() { _error_estimate = NEVER; _event = NEVER; return *this; } TIME_PAIR& min_error_estimate(double E) { if (E < _error_estimate) { _error_estimate = E; }else{ } return *this; } TIME_PAIR& min_event(double E) { if (E < _event) { _event = E; }else{ } return *this; } TIME_PAIR& min(const TIME_PAIR& P) { return min_error_estimate(P._error_estimate).min_event(P._event); } TIME_PAIR& min(double Error_Estimate, double Event) {untested(); return min_error_estimate(Error_Estimate).min_event(Event); } }; /*--------------------------------------------------------------------------*/ inline TIME_PAIR min(TIME_PAIR A, const TIME_PAIR& B) { return A.min(B); } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������src/u_xprobe.cc�������������������������������������������������������������������������������������0000664�0000000�0000000�00000004101�11454012162�0013767�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_xprobe.cc,v 26.110 2009/05/28 15:32:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * extended probe data * used for AC analysis */ //testing=script 2006.07.14 #include "m_phase.h" #include "u_xprobe.h" /*--------------------------------------------------------------------------*/ double XPROBE::operator()(mod_t m, bool db)const { if (exists()) { if (m == mtNONE) { m = _modifier; } double rv = NOT_VALID; switch (m) { case mtNONE: unreachable(); break; case mtMAG: rv = std::abs(_value); break; case mtPHASE: rv = phase(_value); break; case mtREAL: rv = real(_value); break; case mtIMAG: rv = imag(_value); break; } return (db) ? _dbscale * log10(std::max(rv,VOLTMIN)) : rv; }else{ return NOT_VALID; } } /*--------------------------------------------------------------------------*/ XPROBE& XPROBE::operator=(const XPROBE& p) { _value = p._value; _modifier = p._modifier; _dbscale = p._dbscale; return *this; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������src/u_xprobe.h��������������������������������������������������������������������������������������0000664�0000000�0000000�00000005105�11454012162�0013636�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*$Id: u_xprobe.h,v 26.106 2008/12/13 00:48:28 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * extended probe data * used for AC analysis */ //testing=script 2006.07.14 #ifndef U_XPROBE_H #define U_XPROBE_H #include "constant.h" /*--------------------------------------------------------------------------*/ enum mod_t {mtNONE, mtMAG, mtPHASE, mtREAL, mtIMAG}; /*--------------------------------------------------------------------------*/ class XPROBE{ private: COMPLEX _value; mod_t _modifier; // default double _dbscale; // 20 for voltage, 10 for power, etc. explicit XPROBE(): _value(COMPLEX(NOT_VALID, NOT_VALID)), _modifier(mtNONE), _dbscale(20.) {untested();} public: XPROBE(const XPROBE& p): _value(p._value), _modifier(p._modifier), _dbscale(p._dbscale) {untested();} explicit XPROBE(COMPLEX v): _value(v), _modifier(mtMAG), _dbscale(20.) {} explicit XPROBE(COMPLEX v, mod_t m): _value(v), _modifier(m), _dbscale(20.) {} explicit XPROBE(COMPLEX v, mod_t m, double d): _value(v), _modifier(m), _dbscale(d) {} explicit XPROBE(double v): _value(v), _modifier(mtREAL), _dbscale(20.) {} //explicit XPROBE(double v, mod_t m): // _value(v), // _modifier(m), // _dbscale(20.) {} //explicit XPROBE(double v, mod_t m, double d): // _value(v), // _modifier(m), // _dbscale(d) {} ~XPROBE() {} bool exists()const {return _modifier != mtNONE;} double operator()(mod_t m=mtNONE, bool db = false)const; XPROBE& operator=(const XPROBE& p); }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������