pax_global_header00006660000000000000000000000064151511467650014525gustar00rootroot0000000000000052 comment=dfeee909ed9f20b4870dd93423156c0170c0e1ff iverilog-13_0/000077500000000000000000000000001515114676500133515ustar00rootroot00000000000000iverilog-13_0/.gitattributes000066400000000000000000000000771515114676500162500ustar00rootroot00000000000000# gperf in MSYS chokes on DOS line endings *.gperf text eol=lf iverilog-13_0/.github/000077500000000000000000000000001515114676500147115ustar00rootroot00000000000000iverilog-13_0/.github/test.sh000077500000000000000000000004671515114676500162360ustar00rootroot00000000000000#!/usr/bin/env sh echo "Using the bundled ivtest to run regression tests." echo " pwd = $(pwd)" cd ivtest status=0 perl vvp_reg.pl || status=1 if [ "x$1" = "xno-pli1" ] ; then perl vpi_reg.pl || status=1 else perl vpi_reg.pl --with-pli1 || status=1 fi python3 vvp_reg.py || status=1 exit $status iverilog-13_0/.github/workflows/000077500000000000000000000000001515114676500167465ustar00rootroot00000000000000iverilog-13_0/.github/workflows/deploy_docs.yml000066400000000000000000000013521515114676500217760ustar00rootroot00000000000000 name: Deploy documentation on: # Every push onto the main branch regerenates the documentation push: branches: - 'master' jobs: do-deploy: runs-on: ubuntu-latest name: 'Build documentation on Linux' steps: - uses: actions/checkout@v2 - name: Install dependencies run: | sudo apt update -qq sudo apt install -y make autoconf python3-sphinx - name: Make Documentation run: | cd Documentation make html - name: Deploy to GitHub Pages uses: crazy-max/ghaction-github-pages@v2 with: target_branch: gh-pages build_dir: Documentation/_build/html jekyll: false env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} iverilog-13_0/.github/workflows/test.yml000066400000000000000000000054661515114676500204630ustar00rootroot00000000000000name: test on: # Every push onto the main branch triggers a retest. push: branches: - master # All pull_requests trigger a retest. pull_request: workflow_dispatch: jobs: mac: strategy: fail-fast: false runs-on: macos-15-intel name: '🍏 macOS' steps: - uses: actions/checkout@v4 - name: Install dependencies run: | brew install bison pip3 install --break-system-packages docopt - name: Build, check and install run: | export PATH="/usr/local/opt/bison/bin:$PATH" autoconf ./configure --enable-libveriuser make -j$(nproc) check sudo make install - name: Test run: ./.github/test.sh lin: strategy: fail-fast: false matrix: os: [ '22.04', '24.04' ] runs-on: ubuntu-${{ matrix.os }} name: '🐧 Ubuntu ${{ matrix.os }}' steps: - uses: actions/checkout@v4 - name: Install dependencies run: | sudo apt update -qq sudo apt install -y make g++ git bison flex gperf libreadline-dev libbz2-dev autoconf python3-sphinx python3-docopt - name: Build, check and install run: | autoconf ./configure --enable-libveriuser make -j$(nproc) check sudo make install - name: Test run: ./.github/test.sh - name: Documentation run: | cd Documentation make html win: runs-on: windows-latest strategy: fail-fast: false matrix: include: - { msystem: MINGW64, env: x86_64 } - { msystem: UCRT64, env: ucrt-x86_64 } - { msystem: CLANG64, env: clang-x86_64 } name: 🟪 ${{ matrix.msystem}} defaults: run: shell: msys2 {0} env: MINGW_ARCH: ${{ matrix.msystem }} steps: - run: git config --global core.autocrlf input shell: bash - uses: actions/checkout@v4 - uses: msys2/setup-msys2@v2 with: msystem: ${{ matrix.msystem }} update: true install: > git base-devel python-pip mingw-w64-${{ matrix.env }}-perl - uses: actions/setup-python@v5 with: python-version: '>=3.5' - name: Build and check run: | cd msys2 if [ ${{ matrix.msystem }} != "CLANG64" ] ; then export IVL_CONFIG_OPTIONS="--enable-libveriuser" fi makepkg-mingw --noconfirm --noprogressbar -sCLf - name: Install run: pacman -U --noconfirm msys2/*.zst - name: Test run: | if [ ${{ matrix.msystem }} = "CLANG64" ] ; then ./.github/test.sh no-pli1 else ./.github/test.sh fi - uses: actions/upload-artifact@v4 with: name: ${{ matrix.msystem }} path: msys2/*.zst iverilog-13_0/.gitignore000066400000000000000000000030641515114676500153440ustar00rootroot00000000000000# Lines that start with '#' are comments. # # This file is for the development branch of Icarus Verilog. # # The following files will be ignored by git. # Normal editor rules *.swp *~ # Top level generic files tags TAGS cscope.* *.patch *.orig # Object files and libraries *.[oa] *.so gmon*.out gmon*.txt # From autoconf configure config.log config.status Makefile /_pli_types.h config.h /tgt-pcb/pcb_config.h /tgt-pcb/fp.cc /tgt-pcb/fp.h /tgt-pcb/fp.output /tgt-pcb/fp_lex.cc /tgt-vvp/vvp_config.h /tgt-vhdl/vhdl_config.h /vpi/vpi_config.h stamp-*-h /version.h /version_tag.h # Directories autom4te.cache dep # Compiler back end and library files /tgt-vvp/*.conf *.tgt *.vpi /cadpli/cadpli.vpl /tgt-blif/Makefile # lex, yacc and gperf output /driver/cflexor.c /driver/cfparse.c /driver/cfparse.h /driver/cfparse.output /ivlpp/lexor.c /vhdlpp/lexor.cc /vhdlpp/lexor_keyword.cc /vhdlpp/parse.cc /vhdlpp/parse.h /vhdlpp/parse.output /vhdlpp/vhdlpp_config.h /vhdlpp/vhdlpp /lexor.cc /lexor_keyword.cc /parse.cc /parse.h /parse.output /syn-rules.cc /syn-rules.output /vpi/sdf_lexor.c /vpi/sdf_parse.c /vpi/sdf_parse.h /vpi/sdf_parse.output /vpi/sys_readmem_lex.c /vpi/table_mod_lexor.c /vpi/table_mod_parse.c /vpi/table_mod_parse.h /vpi/table_mod_parse.output /vvp/dump.* /vvp/lexor.cc /vvp/parse.cc /vvp/parse.h /vvp/parse.output # Program created files /vvp/tables.cc /iverilog-vpi.man /driver-vpi/res.rc /driver/iverilog.man /vvp/vvp.man # The executables. *.exe /driver/iverilog /iverilog-vpi /ivl /ivlpp/ivlpp /vvp/vvp /ivl.exp /vvp/vvp.exp # Check output /check.vvp iverilog-13_0/AStatement.cc000066400000000000000000000020431515114676500157240ustar00rootroot00000000000000/* * Copyright (c) 2008 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include "config.h" # include "AStatement.h" AContrib::AContrib(PExpr*lv, PExpr*rv) : lval_(lv), rval_(rv) { } AContrib::~AContrib() { delete lval_; delete rval_; } AProcess::~AProcess() { } iverilog-13_0/AStatement.h000066400000000000000000000047741515114676500156030ustar00rootroot00000000000000#ifndef IVL_AStatement_H #define IVL_AStatement_H /* * Copyright (c) 2008-2026 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include # include "ivl_target.h" # include "StringHeap.h" # include "LineInfo.h" # include "Statement.h" # include "PExpr.h" class PExpr; class NetAnalog; class NetScope; class Design; /* * A contribution statement is like an assignment: there is an l-value * expression and an r-value expression. The l-value is a branch probe * expression. */ class AContrib : public Statement { public: AContrib(PExpr*lval, PExpr*rval); ~AContrib() override; AContrib(const AContrib&) = delete; AContrib& operator=(const AContrib&) = delete; virtual void dump(std::ostream&out, unsigned ind) const override; virtual NetProc* elaborate(Design*des, NetScope*scope) const override; private: PExpr*lval_; PExpr*rval_; }; /* * An analog process is not a statement, but contains an analog * statement. The process is where we attach process characteristics * such as initial vs. always, attributes.... */ class AProcess : public LineInfo { public: AProcess(ivl_process_type_t t, Statement*st) : type_(t), statement_(st) { } ~AProcess() override; bool elaborate(Design*des, NetScope*scope) const; ivl_process_type_t type() const { return type_; } Statement*statement() { return statement_; } std::map attributes; // Dump the analog process void dump(std::ostream&out, unsigned ind) const; private: ivl_process_type_t type_; Statement*statement_; private: // not implemented AProcess(const AProcess&); AProcess& operator= (const AProcess&); }; #endif /* IVL_AStatement_H */ iverilog-13_0/Attrib.cc000066400000000000000000000043771515114676500151200ustar00rootroot00000000000000/* * Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include "config.h" # include "Attrib.h" # include Attrib::Attrib() { nlist_ = 0; list_ = 0; } Attrib::~Attrib() { delete[] list_; } const verinum& Attrib::attribute(perm_string key) const { for (unsigned idx = 0 ; idx < nlist_ ; idx += 1) { if (key == list_[idx].key) return list_[idx].val; } static const verinum null; return null; } void Attrib::attribute(perm_string key, const verinum&value) { unsigned idx; for (idx = 0 ; idx < nlist_ ; idx += 1) { if (key == list_[idx].key) { list_[idx].val = value; return; } } struct cell_*tmp = new struct cell_[nlist_+1]; for (idx = 0 ; idx < nlist_ ; idx += 1) tmp[idx] = list_[idx]; tmp[nlist_].key = key; tmp[nlist_].val = value; nlist_ += 1; delete[]list_; list_ = tmp; } bool Attrib::has_compat_attributes(const Attrib&that) const { unsigned idx; for (idx = 0 ; idx < that.nlist_ ; idx += 1) { verinum tmp = attribute(that.list_[idx].key); if (tmp != that.list_[idx].val) return false; } return true; } unsigned Attrib::attr_cnt() const { return nlist_; } perm_string Attrib::attr_key(unsigned idx) const { assert(idx < nlist_); return list_[idx].key; } const verinum& Attrib::attr_value(unsigned idx) const { assert(idx < nlist_); return list_[idx].val; } iverilog-13_0/Attrib.h000066400000000000000000000034041515114676500147500ustar00rootroot00000000000000#ifndef IVL_Attrib_H #define IVL_Attrib_H /* * Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include "StringHeap.h" # include "verinum.h" /* * This class keeps a map of key/value pairs. The map can be set from * an STL map, or by setting individual mappings. */ class Attrib { public: Attrib(); virtual ~Attrib(); const verinum&attribute(perm_string key) const; void attribute(perm_string key, const verinum&value); bool has_compat_attributes(const Attrib&that) const; /* Provide a means of iterating over the entries in the map. */ unsigned attr_cnt() const; perm_string attr_key(unsigned idx) const; const verinum& attr_value(unsigned idx) const; private: struct cell_ { perm_string key; verinum val; }; unsigned nlist_; struct cell_*list_; private: // not implemented Attrib(const Attrib&); Attrib& operator= (const Attrib&); }; #endif /* IVL_Attrib_H */ iverilog-13_0/COPYING000066400000000000000000000432541515114676500144140ustar00rootroot00000000000000 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 Lesser 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 Lesser General Public License instead of this License. iverilog-13_0/Documentation/000077500000000000000000000000001515114676500161625ustar00rootroot00000000000000iverilog-13_0/Documentation/.gitignore000066400000000000000000000000221515114676500201440ustar00rootroot00000000000000_build/ !Makefile iverilog-13_0/Documentation/Makefile000066400000000000000000000011421515114676500176200ustar00rootroot00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build SPHINXPROJ = IcarusVerilog SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)iverilog-13_0/Documentation/conf.py000066400000000000000000000114631515114676500174660ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # Configuration file for the Sphinx documentation builder. # # This file does only contain a selection of the most common options. For a # full list see the documentation: # http://www.sphinx-doc.org/en/master/config # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # # import os # import sys # sys.path.insert(0, os.path.abspath('.')) # -- Project information ----------------------------------------------------- project = 'Icarus Verilog' copyright = '2024-2026, Stephen Williams' author = 'Stephen Williams' # The short X.Y version version = '' # The full version, including alpha/beta/rc tags release = '' # -- General configuration --------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = '.rst' # The master toctree document. master_doc = 'index' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = 'en' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path . exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # If no language is specified, use none highlight_language = 'none' # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'alabaster' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # # html_theme_options = {} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". #html_static_path = ['_static'] html_static_path = [] # Custom sidebar templates, must be a dictionary that maps document names # to template names. # # The default sidebars (for documents that don't match any pattern) are # defined by theme itself. Builtin themes are using these templates by # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', # 'searchbox.html']``. # # html_sidebars = {} html_favicon = 'favicon.ico' # -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. htmlhelp_basename = 'IcarusVerilogdoc' # -- Options for LaTeX output ------------------------------------------------ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # # 'preamble': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'IcarusVerilog.tex', 'Icarus Verilog Documentation', 'Stephen Williams', 'manual'), ] # -- Options for manual page output ------------------------------------------ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'icarusverilog', 'Icarus Verilog Documentation', [author], 1) ] # -- Options for Texinfo output ---------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'IcarusVerilog', 'Icarus Verilog Documentation', author, 'IcarusVerilog', 'One line description of project.', 'Miscellaneous'), ] iverilog-13_0/Documentation/developer/000077500000000000000000000000001515114676500201475ustar00rootroot00000000000000iverilog-13_0/Documentation/developer/getting_started.rst000066400000000000000000000223451515114676500240760ustar00rootroot00000000000000 Getting Started as a Contributor ================================ Icarus Verilog development is centered around the github repository at `github.com/steveicarus/iverilog `_. Contributing to Icarus Verilog requires a basic knowledge of git and github, so see the github documentation for more information. The sections below will step you through the basics of getting the source code from github, making a branch, and submitting a pull request for review. Getting Icarus Verilog ---------------------- To start, you will need to clone the code. It is preferred that you use the "ssh" method, and the ssh based clone with the command: .. code-block:: console % git clone git@github.com:steveicarus/iverilog.git This assumes that you have a github account (accounts are free) and you have set up your ssh authentication keys. See the `Authentication Guides here `_. The "git clone" command will get you all the source: .. code-block:: console % git clone git@github.com:steveicarus/iverilog.git Cloning into 'iverilog'... remote: Enumerating objects: 66234, done. remote: Counting objects: 100% (6472/6472), done. remote: Compressing objects: 100% (4123/4123), done. remote: Total 66234 (delta 2412), reused 6039 (delta 2190), pack-reused 59762 Receiving objects: 100% (66234/66234), 27.98 MiB | 2.53 MiB/s, done. Resolving deltas: 100% (50234/50234), done. % cd iverilog/ Normally, this is enough as you are now pointing at the most current development code, and you have implicitly created a branch "master" that tracks the development head. However, If you want to actually be working on a specific version, say for example version 11, the v11-branch, you checkout that branch with the command: .. code-block:: console % git checkout --track -b v11-branch origin/v11-branch This creates a local branch that tracks the v11-branch in the repository, and switches you over to your new v11-branch. The tracking is important as it causes pulls from the repository to re-merge your local branch with the remote v11-branch. You always work on a local branch, then merge only when you push/pull from the remote repository. Now that you've cloned the repository and optionally selected the branch you want to work on, your local source tree may later be synced up with the development source by using the git command: .. code-block:: console % git pull Already up to date. Finally, configuration files are built by the extra step: .. code-block:: console % sh autoconf.sh Autoconf in root... Precompiling lexor_keyword.gperf Precompiling vhdlpp/lexor_keyword.gperf You will need autoconf and gperf installed in order for the script to work. If you get errors such as: .. code-block:: console % sh autoconf.sh Autoconf in root... autoconf.sh: 10: autoconf: not found Precompiling lexor_keyword.gperf autoconf.sh: 13: gperf: not found. You will need to install download and install the autoconf and gperf tools. Now you are ready to configure and compile the source. Icarus Specific Configuration Options ------------------------------------- Icarus takes many of the standard configuration options and those will not be described here. The following are specific to Icarus Verilog: .. code-block:: none --enable-suffix[=suffix] This option allows the user to build Icarus with a default suffix or when provided a user defined suffix. All programs or directories are tagged with this suffix. e.g.(iverilog-0.8, vvp-0.8, etc.). The output of iverilog will reference the correct run time files and directories. The run time will check that it is running a file with a compatible version e.g.(you can not run a V0.9 file with the V0.8 run time). .. code-block:: none --enable-libvvp The vvp program is built as a small stub linked to a shared library, libvvp.so, that may be linked with other programs so that they can host a vvp simulation. .. code-block:: none --enable-libveriuser PLI version 1 (the ACC and TF routines) were deprecated in IEEE 1364-2005. These are supported in Icarus Verilog by the libveriuser library and cadpli module. Starting with v13, these will only be built if this option is used. A debug options is: .. code-block:: none --with-valgrind This option adds extra memory cleanup code and pool management code to allow better memory leak checking when valgrind is available. This option is not needed when checking for basic errors with valgrind. Compiling on Linux ------------------ (Note: You will need to install bison, flex, g++ and gcc) This is probably the easiest step. Given that you have the source tree from the above instructions, the compile and install is generally as simple as: .. code-block:: console % ./configure configure: loading site script /usr/share/site/x86_64-unknown-linux-gnu checking build system type... x86_64-unknown-linux-gnu checking host system type... x86_64-unknown-linux-gnu checking for gcc... gcc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... [...and so on...] % make mkdir dep Using git-describe for VERSION_TAG g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c main.cc -o main.o mv main.d dep/main.d g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c async.cc -o async.o mv async.d dep/async.d g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c design_dump.cc -o design_dump.o mv design_dump.d dep/design_dump.d g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c discipline.cc -o discipline.o [...and so on...] The end result is a complete build of Icarus Verilog. You can install your compiled version with a command like this: .. code-block:: console % sudo make install Regression Tests ---------------- Icarus Verilog comes with a fairly extensive regression test suite. As of 2022, that test suite is included with the source in the "ivtest" directory. Contained in that directory are a couple driver scripts that run all the regression tests on the installed version of Icarus Verilog. So for example: .. code-block:: console % cd ivtest % ./vvp_reg.pl % ./vvp_reg.py % ./vpi_reg.pl will run all the regression tests for the simulation engine. (This is what most people will want to do.) You should rerun these tests before submitting patches to the developers. Also, if you are adding a new feature, you should add test programs to the regression test suite to validate your new feature (or bug fix.). The python script is the preferred method to add new tests. All of these scripts take other options to test various configurations. What options are supported can be found by using the ``-h/--help`` argument. There is also a separate ``vlog95_reg.pl`` script for testing the vlog95 translation of the original tests. This is integrated into the existing Python test script for the new tests. Note that pull requests will be required to pass these regression tests before being merged. Forks, Branches and Pull Requests --------------------------------- Currently, the preferred way to submit patches to Icarus Verilog is via pull requests. `Pull requests `_ can be created from the main repository if you have write access (very few people have write access) or more commonly from a fork, so the first step is to create a fork that you can work with. It is easy enough to create a fork, just go to the `github.com/steveicarus/iverilog `_ page and use the "fork" button in the upper right corner. This will create a new repository that you can clone instead of the steveicarus/iverilog repository. You then use your local repository to create feature branches, then submit them for inclusion in the main repository as pull requests. Remember to `synchronize your fork `_ periodically with the main repository. This will make sure your work is based on the latest upstream and avoid merge conflicts. Create your patch by first creating a branch that contains your commits: .. code-block:: console % git checkout -b my-github-id/branch-name We are encouraging using this scheme for naming your branches that are destined for pull requests. Use your github id in the branch name. So for example: .. code-block:: console % git checkout -b steveicarus/foo-feature Do your work in this branch, then when you are ready to create a pull request, first push the branch up to github: .. code-block:: console % git push -u origin my-github-id/branch-name Then go to github.com to create your pull request. `Create your pull request against the "master" branch of the upstream repository `_, or the version branch that you are working on. Your pull request will be run through continuous integration, and reviewed by one of the main authors. Feedback may be offered to your PR, and once accepted, an approved individual will merge it for you. Then you are done. iverilog-13_0/Documentation/developer/glossary.rst000066400000000000000000000034001515114676500225410ustar00rootroot00000000000000 Glossary ======== Throughout Icarus Verilog descriptions and source code, I use a variety of terms and acronyms that might be specific to Icarus Verilog, have an Icarus Verilog specific meaning, or just aren't widely known. So here I define these terms. LRM - Language Reference Manual This is a generic acronym, but in the Verilog world we sometimes mean *the* language reference manual, the IEEE1364 standard. PLI - Programming Language Interface This is a C API into Verilog simulators that is defined by the IEEE1364. There are two major interfaces, sometimes called PLI 1 and PLI 2. PLI 2 is also often called VPI. UDP - User Defined Primitive These are objects that Verilog programmers define with the "primitive" keyword. They are truth-table based devices. The syntax for defining them is described in the LRM. VPI - Verilog Procedural Interface This is the C API that is defined by the Verilog standard, and that Icarus Verilog partially implements. See also PLI. VVM - Verilog Virtual Machine This is the Icarus Verilog runtime that works with the code generator that generates C++. VVP - Verilog Virtual Processor This is the Icarus Verilog runtime that reads in custom code in a form that I call "VVP Assembly". LPM - Library of Parameterized Modules LPM (Library of Parameterized Modules) is EIS-IS standard 103-A. It is a standard library of abstract devices that are designed to be close enough to the target hardware to be easily translated, yet abstract enough to support a variety of target technologies without excessive constraints. Icarus Verilog uses LPM internally to represent idealized hardware, especially when doing target neutral synthesis. iverilog-13_0/Documentation/developer/guide/000077500000000000000000000000001515114676500212445ustar00rootroot00000000000000iverilog-13_0/Documentation/developer/guide/cadpli/000077500000000000000000000000001515114676500225005ustar00rootroot00000000000000iverilog-13_0/Documentation/developer/guide/cadpli/cadpli.rst000066400000000000000000000031631515114676500244710ustar00rootroot00000000000000 Cadence PLI1 Modules ==================== With the cadpli module, Icarus Verilog is able to load PLI1 applications that were compiled and linked to be dynamic loaded by Verilog-XL or NC-Verilog. This allows Icarus Verilog users to run third-party modules that were compiled to interface with XL or NC. Obviously, this only works on the operating system that the PLI application was compiled to run on. For example, a Linux module can only be loaded and run under Linux. Icarus Verilog uses an interface module, the "cadpli" module, to connect the worlds. This module is installed with Icarus Verilog, and is invoked by the usual -m flag to iverilog or vvp. This module in turn scans the extended arguments, looking for +cadpli= arguments. The latter specify the share object and bootstrap function for running the module. For example, to run the module product.so, that has the bootstrap function "my_boot":: vvp -mcadpli a.out -cadpli=./product.so:my_boot The "-mcadpli" argument causes vvp to load the cadpli.vpl library module. This activates the -cadpli= argument interpreter. The -cadpli=: argument, then, causes vvp, through the cadpli module, to load the loadable PLI application, invoke the my_boot function to get a veriusertfs table, and scan that table to register the system tasks and functions exported by that object. The format of the -cadpli= extended argument is essentially the same as the +loadpli1= argument to Verilog-XL. The integration from this point is seamless. The PLI application hardly knows that it is being invoked by Icarus Verilog instead of Verilog-XL, so operates as it would otherwise. iverilog-13_0/Documentation/developer/guide/index.rst000066400000000000000000000146251515114676500231150ustar00rootroot00000000000000 Developer Guide =============== The developer guide is intended to give you a gross structure of the Icarus Verilog compiler source. This will help orient you to the source code itself, so that you can find the global parts where you can look for even better detail. The documentation for getting, building and installing Icarus Verilog is kept and maintained at :doc:`Getting Started as a Contributer <../getting_started>` See the Installation Guide for getting the current source from the git repository (and how to use the git repository) and see the Developer Guide for instructions on participating in the Icarus Verilog development process. That information will not be repeated here. Scroll down to a listing with further readings. Compiler Components ------------------- - The compiler driver (driver/) This is the binary that is installed as "iverilog". This program takes the command line arguments and assembles invocations of all the other subcommands to perform the steps of compilation. - The preprocessor (ivlpp/) This implements the Verilog pre-processor. In Icarus Verilog, the compiler directives \`define, \`include, \`ifdef and etc. are implemented in an external program. The ivlpp/ directory contains the source for this program. - The core compiler (root directory) The "ivl" program is the core that does all the Verilog compiler processing that is not handled elsewhere. This is the main core of the Icarus Verilog compiler, not the runtime. See below for more details on the core itself. - The loadable code generators (tgt-\*/) This core compiler, after it is finished with parsing and semantic analysis, uses loadable code generators to emit code for supported targets. The tgt-\*/ directories contains the source for the target code generators that are bundled with Icarus Verilog. The tgt-vvp/ directory in particular contains the code generator for the vvp runtime. Runtime Components ------------------ - The vvp runtime (vvp/) This program implements the runtime environment for Icarus Verilog. It implements the "vvp" command described in the user documentation. See the vvp/ subdirectory for further developer documentation. - The system tasks implementations (vpi/) The standard Verilog system tasks are implemented using VPI (PLI-2) and the source is in this subdirectory. - The PLI-1 compatibility library (libveriuser/) The Icarus Verilog support for the deprecated PLI-1 is in this subdirectory. The vvp runtime does not directly support the PLI-1. Instead, the libveriuser library emulates it using the builtin PLI-2 support. - The Cadence PLI module compatibility module (cadpli/) It is possible in some specialized situations to load and execute PLI-1 code written for Verilog-XL. This directory contains the source for the module that provides the Cadence PLI interface. The Core Compiler ----------------- The "ivl" binary is the core compiler that does the heavy lifting of compiling the Verilog source (including libraries) and generating the output. This is the most complex component of the Icarus Verilog compilation system. The process in the abstract starts with the Verilog lexical analysis and parsing to generate an internal "pform". The pform is then translated by elaboration into the "netlist" form. The netlist is processed by some functors (which include some optimizations and optional synthesis) then is translated into the ivl_target internal form. And finally, the ivl_target form is passed via the ivl_target.h API to the code generators. - Lexical Analysis Lexical analysis and parsing use the tools "flex", "gperf", and "bison". The "flex" input file "lexor.lex" recognizes the tokens in the input stream. This is called "lexical analysis". The lexical analyzer also does some processing of compiler directives that are not otherwise taken care of by the external preprocessor. The lexical analyzer uses a table of keywords that is generated using the "gperf" program and the input file "lexor_keywords.gperf". This table allows the lexical analyzer to efficiently check input words with the rather large set of potential keywords. - Parsing The parser input file "parse.y" is passed to the "bison" program to generate the parser. The parser uses the functions in parse*.h, parse*.cc, pform.h, and pform*.cc to generate the pform from the stream of input tokens. The pform is what compiler writers call a "decorated parse tree". The pform itself is described by the classes in the header files "PScope.h", "Module.h", "PGenerate.h", "Statement.h", and "PExpr.h". The implementations of the classes in those header files are in the similarly named C++ files. - Elaboration Elaboration transforms the pform to the netlist form. Elaboration is conceptually divided into several major steps: Scope elaboration, parameter overrides and defparam propagation, signal elaboration, and statement and expression elaboration. The elaboration of scopes and parameter overrides and defparam propagation are conceptually separate, but are in practice intermingled. The elaboration of scopes scans the pform to find and instantiate all the scopes of the design. New scopes are created by instantiation of modules (starting with the root instances) by user defined tasks and functions, named blocks, and generate schemes. The elaborate_scope methods implement scope elaboration, and the elab_scope.cc source file has the implementations of those methods. The elaborate.cc source file contains the initial calls to the elaborate_scope for the root scopes to get the process started. In particular, see the "elaborate" function near the bottom of the elaborate.cc source file. The calls to Design::make_root_scope create the initial root scopes, and the creation and enqueue of the elaborate_root_scope_t work items primes the scope elaboration work list. Intermingled in the work list are defparms work items that call the Design::run_defparams and Design::evaluate_parameters methods that override and evaluate parameters. The override and evaluation of parameters must be intermingled with the elaboration of scopes because the exact values of parameters may impact the scopes created (imagine generate schemes and instance arrays) and the created scopes in turn create new parameters that need override and evaluation. Further Reading --------------- For further information on the individual parts of Icarus Verilog, see this listing: .. toctree:: :maxdepth: 2 ivl/index vvp/index tgt-vvp/tgt-vvp vpi/index cadpli/cadpli misc/index iverilog-13_0/Documentation/developer/guide/ivl/000077500000000000000000000000001515114676500220365ustar00rootroot00000000000000iverilog-13_0/Documentation/developer/guide/ivl/attributes.rst000066400000000000000000000057431515114676500247670ustar00rootroot00000000000000 Icarus Verilog Attributes ========================= Attribute Naming Conventions ---------------------------- Attributes that are specific to Icarus Verilog, and are intended to be of use to programmers, start with the prefix "ivl\_". Attributes with the "_ivl_" prefix are set aside for internal use. They may be generated internally by the compiler. They need not be documented here. Attributes To Control Synthesis ------------------------------- The following is a summary of Verilog attributes that Icarus Verilog understands within Verilog source files to control synthesis behavior. This section documents generic synthesis attributes. For target specific attributes, see target specific documentation. These attributes only effect the behavior of the synthesizer. For example, the ivl_combinational will not generate an error message if the Verilog is being compiled for simulation. (It may generate a warning.) * Attributes for "always" and "initial" statements (\* ivl_combinational \*) This attribute tells the compiler that the statement models combinational logic. If the compiler finds that it cannot make combinational logic out of a marked always statement, it will report an error. This attribute can be used to prevent accidentally inferring latches or flip-flops where the user intended combinational logic. (\* ivl_synthesis_on \*) This attribute tells the compiler that the marked always statement is synthesizable. The compiler will attempt to synthesize the code in the marked "always" statement. If it cannot in any way synthesize it, then it will report an error. (\* ivl_synthesis_off \*) If this value is attached to an "always" statement, then the compiler will *not* synthesize the "always" statement. This can be used, for example, to mark embedded test bench code. * Attributes for modules (\* ivl_synthesis_cell \*) If this value is attached to a module during synthesis, that module will be considered a target architecture primitive, and its interior will not be synthesized further. The module can therefore hold a model for simulation purposes. * Attributes for signals (wire/reg/integer/tri/etc.) (\* PAD = "" \*) If this attribute is attached to a signal that happens to be a root module port, then targets that support it will use the string value as a list of pin assignments for the port/signal. The format is a comma separated list of location tokens, with the format of the token itself defined by the back-end tools in use. * Other Attributes [ none defined yet ] Misc ---- (\* _ivl_schedule_push \*) If this attribute is attached to a thread object (always or initial statement) then the vvp code generator will generate code that causes the scheduler to push this thread at compile time. The compiler may internally add this attribute to always statements if it detects that it is combinational. This helps resolve time-0 races. iverilog-13_0/Documentation/developer/guide/ivl/index.rst000066400000000000000000000002071515114676500236760ustar00rootroot00000000000000 IVL - The Core Compiler ======================= .. toctree:: :maxdepth: 1 netlist attributes ivl_target lpm t-dll iverilog-13_0/Documentation/developer/guide/ivl/ivl_target.rst000066400000000000000000000115751515114676500247410ustar00rootroot00000000000000 Loadable Target API (ivl_target) ================================ In addition to the standard VPI API, Icarus Verilog supports a non-standard loadable target module API. This API helps C programmers write modules that Icarus Verilog can use to generate code. These modules are used at compile time to write the elaborated design to the simulation or netlist files. For example, the vvp code generator is a loadable target module that writes vvp code into the specified file. Loadable target modules gain access to the 'elaborated' design. That means, the source files have been checked for syntax and correctness, any synthesis and general optimization steps have been performed, and what is left is a design that reflects but is not exactly the same as the input Verilog source code. This relieves the modules of the burden of supporting all the odd corners and complexities of the Verilog language. The Target Module API --------------------- The API is defined in the header file "ivl_target.h" which is installed with Icarus Verilog. The header defines the functions that the module writer can use to get at the elaborated design during the course of writing the output format. The target module API function "target_design" is special in that the API does not provide this function: The target module itself provides it. When the compiler loads the target module, it invokes the "target_design" function with a handle to the design. This is the point where the target module takes over to process the design. Compiling Target Modules ------------------------ Compiling loadable target modules is similar to compiling VPI modules, in that the module must be compiled with the "-fPIC" flag to gcc, and linked with the "-shared" flag. The module that you compile is then installed in a place where the "iverilog" command can find it, and configuration files are adjusted to account for the new module. This code:: # include int target_design(ivl_design_t des) { return 0; } is an example module that we can write into the file "empty.c"; and let us compile it into the module file "empty.tgt" like so:: % gcc -o empty.tgt -fpic -shared empty.c This makes the "empty.tgt" file an a dynamically loaded shared object. Creating the Target Config File ------------------------------- The target config file tells the Icarus Verilog core how to process your new code generator. The ivl core expects two configuration files: the name.conf and the name-s.config files. The "-s" version is what is used if the user gives the "-S" (synthesis) flag on the command line. The stub target, included in most distributions, demonstrates the config files. The "stub.conf" file is:: functor:cprop functor:nodangle -t:dll flag:DLL=stub.tgt and the "stub-s.conf" file is:: functor:synth2 functor:synth functor:syn-rules functor:cprop functor:nodangle -t:dll flag:DLL=stub.tgt Note that the "stub-s.conf" file contains more lines to invoke internal synthesis functions, whereas the "stub.conf" invokes only the basic optimization steps. In general, only the last line (The "flag:DLL=.tgt" record) varies for each target. For your target, replace the with the name of your target and you have a configuration file ready to install. Note that this is the name of your target module. This is in fact how the config file tells the compiler the name of your module. The rest of the config file is best taken as boiler plate and installed as is, with one difference. If your target is a synthesis target (for example a mosis code generator or a pld code generator) that expects synthesis to happen, then it makes the most sense to create both your config file like the "stub-s.conf" config file. This causes the compiler to do synthesis for your target whether the user gives the "-S" flag or not. Installing the Target Module ---------------------------- Finally, the "empty.conf", the "empty-s.conf" and the "empty.tgt" files need to be installed. Where they go depends on your system, but in Linux they are normally installed in "/usr/lib/ivl". LPM Devices ----------- All LPM devices support a small set of common LPM functions, as described in the ivl_target header file. The ivl_lpm_t object has a type enumerated by ivl_lpm_type_t, and that type is accessible via the ivl_lpm_type function. The following are type specific aspects of LPM devices. * IVL_LPM_UFUNC This LPM represents a user defined function. It is a way to connect behavioral code into a structural network. The UFUNC device has a vector output and a set of inputs. The ivl_lpm_define function returns the definition as an ivl_scope_t object. The output vector is accessible through the ivl_lpm_q, and the output has the width defined by ivl_lpm_width. This similar to most every other LPM device with outputs. There are ivl_lpm_size() input ports, each with the width ivl_lpm_data2_width(). The actual nexus is indexed by ivl_lpm_data2(). iverilog-13_0/Documentation/developer/guide/ivl/lpm.rst000066400000000000000000000022611515114676500233610ustar00rootroot00000000000000 What Is LPM =========== LPM (Library of Parameterized Modules) is EIS-IS standard 103-A. It is a standard library of abstract devices that are designed to be close enough to the target hardware to be easily translated, yet abstract enough to support a variety of target technologies without excessive constraints. Icarus Verilog uses LPM internally to represent idealized hardware, especially when doing target neutral synthesis. In general, the user does not even see the LPM that Icarus Verilog generates, because the LPM devices are translated into technology specific devices by the final code generator or target specific optimizers. Internal Uses Of LPM -------------------- Internally, Icarus Verilog uses LPM devices to represent the design in abstract, especially when synthesizing such functions as addition, flip-flops, etc. The `synth` functor generates LPM modules when interpreting procedural constructs. The functor generates the LPM objects needed to replace a behavioral description, and uses attributes to tag the devices with LPM properties. Code generators need to understand the supported LPM devices so that they can translate the devices into technology specific devices. iverilog-13_0/Documentation/developer/guide/ivl/netlist.rst000066400000000000000000000314141515114676500242550ustar00rootroot00000000000000 Netlist Format ============== The output from the parse and elaboration steps is a "netlist" rooted in a Design object. Parsing translates the design described in the initial source file into a temporary symbolic "pform". Elaboration then expands the design, resolving references and expanding hierarchies, to produce a flattened netlist. This is the form that optimizers and code generators use. The design optimization processes all manipulate the netlist, translating it to a (hopefully) better netlist after each step. The complete netlist is then passed to the code generator, the emit function, where the final code (in the target format) is produced. Structural Items: NetNode and NetNet ------------------------------------ Components and wires, memories and registers all at their base are either NetNode objects or NetNet objects. Even these classes are derived from the NetObj class. All NetNode and NetNet objects have a name and some number of pins. The name usually comes from the Verilog source that represents that object, although objects that are artifacts of elaboration will have a generated (and probably unreadable) name. The pins are the ports into the device. NetNode objects have a pin for each pin of the component it represents, and NetNet objects have a pin for each signal in the vector. Node and net pins can be connected together via the connect function. Connections are transitive (A==B and B==c means A==C) so connections accumulate on a link as items are connected to it. The destructors for nets and nodes automatically arrange for pins to be disconnected when the item is deleted, so that the netlist can be changed during processing. Structural Links ---------------- The NetNode and NetNet classes contain arrays of Link objects, one object per pin. Each pin is a single bit. The Link objects link to all the NetNode and NetNet objects' links that are connected together in the design, and to a Nexus object. This way, code that examines a node of the design can discover what is connected to each pin. The connected set of links also has common properties that are stored or access from the Nexus object. All the Links that are connected together are also connected to a single Nexus object. This object is useful for accessing the properties and values that come from the connected set of links. The Nexus object is also handy for iterating over the connected set of Links. See the Link class definition in netlist.h for a description of the link methods, and the Nexus class for nexus global methods. Currently, a link has 3 possible direction properties: PASSIVE -- These pins are sampled by the object that holds the pin based on some external event. These are used, for example, by NetESignal objects that read a point for a procedural expression. INPUT -- These pins potentially react to the setting of its input. OUTPUT -- These pins potentially drive the node. (They may be three-state.) Behavioral Items: NetProcTop, NetProc and derived classes --------------------------------------------------------- Behavioral items are not in general linked to the netlist. Instead, they represent elaborated behavioral statements. The type of the object implies what the behavior of the statement does. For example, a NetCondit object represents an `if` statement, and carries a condition expression and up to two alternative sub-statements. At the root of a process is a NetProcTop object. This class carries a type flag (initial or always) and a single NetProc object. The contained statement may, depending on the derived class, refer to other statements, compound statements, so on. But at the root of the tree is the NetProcTop object. The Design class keeps a list of the elaborated NetProcTop objects. That list represents the list of processes in the design. Interaction Of Behavioral And Structural: NetAssign\_ ----------------------------------------------------- The behavioral statements in a Verilog design effect the structural aspects through assignments to registers. Registers are structural items represented by the NetNet class, linked to the assignment statement through pins. This implies that the l-value of an assignment is structural. It also implies that the statement itself is structural, and indeed it is derived from NetNode. The NetAssign\_ class is also derived from the NetProc class because what it does is brought on by executing the process. By multiple inheritance we have therefore that the assignment is both a NetNode and a NetProc. The NetAssign\_ node has pins that represent the l-value of the statement, and carries behavioral expressions that represent the r-value of the assignment. Memories -------- The netlist form includes the NetMemory type to hold the content of a memory. Instances of this type represent the declaration of a memory, and occur once for each memory. References to the memory are managed by the NetEMemory and NetAssignMem\_ classes. An instance of the NetEMemory class is created whenever a procedural expression references a memory element. The operand is the index to use to address (and read) the memory. An instance of the NetAssignMem\_ class is created when there is a procedural assignment to the memory. The NetAssignMem\_ object represents the l-value reference (a write) to the memory. As with the NetEMemory class, this is a procedural reference only. When a memory reference appears in structural context (i.e. continuous assignments) elaboration creates a NetRamDq. This is a LPM_RAM_DQ device. Elaboration leaves the write control and data input pins unconnected for now, because memories cannot appear is l-values of continuous assignments. However, the synthesis functor may connect signals to the write control lines to get a fully operational RAM. By the time elaboration completes, there may be many NetAssignMem\_, NetEMemory and NetRamDq objects referencing the same NetMemory object. Each represents a port into the memory. It is up to the synthesis steps (and the target code) to figure out what to do with these ports. Expressions ----------- Expressions are represented as a tree of NetExpr nodes. The NetExpr base class contains the core methods that represent an expression node, including virtual methods to help with dealing with nested complexities of expressions. Expressions (as expressed in the source and p-form) may also be elaborated structurally, where it makes sense. For example, assignment l-value expressions are represented as connections to pins. Also, continuous assignment module items are elaborated as gates instead of as a procedural expression. Event expressions are also elaborated structurally as events are like devices that trigger behavioral statements. However, typical expressions the behavioral description are represented as a tree of NetExpr nodes. The derived class of the node encodes what kind of operator the node represents. Expression Bit Width -------------------- The expression (represented by the NetExpr class) has a bit width that it either explicitly specified, or implied by context or contents. When each node of the expression is first constructed during elaboration, it is given, by type and parameters, an idea what its width should be. It certain cases, this is definitive, for example with signals. In others, it is ambiguous, as with unsized constants. As the expression is built up by elaboration, operators that combine expressions impose bit widths of the environment or expose the bit widths of the sub expressions. For example, the bitwise AND (&) operator has a bit size implied by its operands, whereas the comparison (==) operator has a bit size of 1. The building up of the elaborated expression checks and adjusts the bit widths as the expression is built up, until finally the context of the expression takes the final bit width and makes any final adjustments. The NetExpr::expr_width() method returns the calculated (or guessed) expression width. This method will return 0 until the width is set by calculation or context. If this method returns false, then it is up to the context that wants the width to set one. The elaboration phase will call the NetExpr::set_width method on an expression as soon as it gets to a point where it believes that it knows what the width should be. The NetExpr::set_width(unsigned) virtual method is used by the context of an expression node to note to the expression that the width is determined and please adapt. If the expression cannot reasonably adapt, it will return false. Otherwise, it will adjust bit widths and return true. :: I do not yet properly deal with cases where elaboration knows for certain that the bit width does not matter. In this case, I really should tell the expression node about it so that it can pick a practical (and optimal) width. Interaction Of Expressions And Structure: NetESignal ---------------------------------------------------- The NetAssign\_ class described above is the means for processes to manipulate the net, but values are read from the net by NetESignal objects. These objects are class NetExpr because they can appear in expressions (and have width). They are not NetNode object, but hold pointers to a NetNet object, which is used to retrieve values with the expression is evaluated. Hierarchy In Netlists --------------------- The obvious hierarchical structure of Verilog is the module. The Verilog program may contain any number of instantiations of modules in order to form an hierarchical design. However, the elaboration of the design into a netlist erases module boundaries. Modules are expanded each place they are used, with the hierarchical instance name used to name the components of the module instance. However, the fact that a wire or register is a module port is lost. The advantage of this behavior is first the simplification of the netlist structure itself. Backends that process netlists only need to cope with a list of nets, a list of nodes and a list of processes. This eases the task of the backend code generators. Another advantage of this flattening of the netlist is that optimizers can operate globally, with optimizations freely crossing module boundaries. This makes coding of netlist transform functions such as constant propagation more effective and easier to write. Scope Representation In Netlists -------------------------------- In spite of the literal flattening of the design, scope information is preserved in the netlist, with the NetScope class. The Design class keeps a single pointer to the root scope of the design. This is the scope of the root module. Scopes that are then created within that (or any nested) module are placed as children of the root scope, and those children can have further children, and so on. Each scope in the tree carries its own name, and its relationship to its parent and children. This makes it possible to walk the tree of scopes. In practice, the walking of the scopes is handled by recursive methods. Each scope also carries the parameters that are applicable to the scope itself. The parameter expression (possibly evaluated) can be located by name, given the scope object itself. The scan of the pform to generate scopes also places the parameters that are declared in the scope. Overrides are managed during the scan, and once the scan is complete, defparam overrides are applied. Tasks In Netlists ----------------- The flattening of the design does not include tasks and named begin-end blocks. Tasks are behavioral hierarchy (whereas modules are structural) so do not easily succumb to the flattening process. In particular, it is logically impossible to flatten tasks that recurse. (The elaboration process does reserve the right to flatten some task calls. C++ programmers recognize this as inlining a task.) Time Scale In Netlists ---------------------- The Design class and the NetScope classes carry time scale and resolution information of the elaborated design. There is a global resolution, and there are scope specific units and resolutions. Units and resolutions are specified as signed integers, and interpreted as the power of 10 of the value. For example, a resolution "-9" means that "1" is 1ns (1e-9). The notation supports units from -128 to +127. It is up to the back-ends to interpret "-4" as "100us". Delays are expressed in the netlist by integers. The units of these delays are always given in the units of the design precision. This allows everything to work with integers, and generally places the burden of scaling delays into elaboration. This is, after all, a common task. The Design::get_precision() method gets the global design precision. Each NetScope also carries its local time_units and time_precision values. These are filled in during scope elaboration and are used in subsequent elaboration phases to arrange for scaling of delays. This information can also be used by the code generator to scale times back to the units of the scope, if that is desired. iverilog-13_0/Documentation/developer/guide/ivl/t-dll.rst000066400000000000000000000042571515114676500236140ustar00rootroot00000000000000 Loadable Targets ================ Icarus Verilog supports dynamically loading code generator modules to perform the back-end processing of the completed design. The user specifies on the command line the module to load. The compiler loads the module (once the design is compiled and elaborated) and calls it to finally handle the design. Loadable target modules implement a set of functions that the core compiler calls to pass the design to it, and the module in turn uses a collection of functions in the core (the API) to access details of the design. Loading Target Modules ---------------------- The target module loader is invoked with the ivl flag "-tdll". That is, the DLL loader is a linked in target type. The name of the target module to load is then specified with the DLL flag, i.e. "-fDLL=". Compiling Target Modules ------------------------ Loadable Target Module Api -------------------------- The target module API is defined in the ivl_target.h header file. This declares all the type and functions that a loadable module needs to access the design. About Specific Expression Types ------------------------------- In this section find notes about the various kinds of expression nodes. The notes here are in addition to the more general documentation in the ivl_target.h header file. * IVL_EX_CONCAT The concatenation operator forms an expression node that holds the repeat count and all the parameter expressions. The repeat count is an integer that is calculated by the core compiler so it fully evaluated, and *not* an expression. The parameter expressions are retrieved by the ivl_expr_parm method, with the index increasing as parameters go from left to right, from most significant to least significant. (Note that this is different from the order of bits within an expression node.) * IVL_EX_NUMBER This is a constant number. The width is fully known, and the bit values are all represented by the ASCII characters 0, 1, x or z. The ivl_expr_bits method returns a pointer to the least significant bit, and the remaining bits are ordered from least significant to most significant. For example, 5'b1zzx0 is the 5 character string "0xzz1". iverilog-13_0/Documentation/developer/guide/misc/000077500000000000000000000000001515114676500221775ustar00rootroot00000000000000iverilog-13_0/Documentation/developer/guide/misc/ieee1364-notes.rst000066400000000000000000000463611515114676500253160ustar00rootroot00000000000000 IEEE1364 Notes ============== The IEEE1364 standard is the bible that defines the correctness of the Icarus Verilog implementation and behavior of the compiled program. The IEEE1364.1 is also referenced for matters of synthesis. So the ultimate definition of right and wrong comes from those documents. That does not mean that a Verilog implementation is fully constrained. The standard document allows for implementation specific behavior that, when properly accounted for, does not effect the intended semantics of the specified language. It is therefore possible and common to write programs that produce different results when run by different Verilog implementations. Standardization Issues ---------------------- These are some issues where the IEEE1364 left unclear, unspecified or simply wrong. I'll try to be precise as I can, and reference the standard as needed. I've made implementation decisions for Icarus Verilog, and I will make clear what those decisions are and how they affect the language. * OBJECTS CAN BE DECLARED ANYWHERE IN THE MODULE Consider this module:: module sample1; initial foo = 1; reg foo; wire tmp = bar; initial #1 $display("foo = %b, bar = %b", foo, tmp); endmodule Notice that the `reg foo;` declaration is placed after the first initial statement. It turns out that this is a perfectly legal module according to the -1995 and -2000 versions of the standard. The statement `reg foo;` is a module_item_declaration which is in turn a module_item. The BNF in the appendix of IEEE1364-1995 treats all module_item statements equally, so no order is imposed. Furthermore, there is no text (that I can find) elsewhere in the standard that imposes any ordering restriction. The sorts of restrictions I would look for are "module_item_declarations must appear before all other module_items" or "variables must be declared textually before they are referenced." Such statements simply do not exist. (Personally, I think it is fine that they don't.) The closest is the rules for implicit declarations of variables that are otherwise undeclared. In the above example, `bar` is implicitly declared and is therefore a wire. However, although `initial foo = 1;` is written before foo is declared, foo *is* declared within the module, and declared legally by the BNF of the standard. Here is another example:: module sample2; initial x.foo = 1; test x; initial #1 $display("foo = %b", x.foo); endmodule module test; reg foo; endmodule; From this example one can clearly see that foo is once again declared after its use in behavioral code. One also sees a forward reference of an entire module. Once again, the standard places no restriction on the order of module declarations in a source file, so this program is, according to the standard, perfectly well formed. Icarus Verilog interprets both of these examples according to "The Standard As I Understand It." However, commercial tools in general break down with these programs. In particular, the first example may generate different errors depending on the tool. The most common error is to claim that `foo` is declared twice, once (implicitly) as a wire and once as a reg. So the question now becomes, "Is the standard broken, or are the tools limited?" Coverage of the standard seems to vary widely from tool to tool so it is not clear that the standard really is at fault. It is clear, however, that somebody goofed somewhere. My personal opinion is that there is no logical need to require that all module_item_declarations precede any other module items. I personally would oppose such a restriction. It may make sense to require that declarations of variables within a module be preceded by their use, although even that is not necessary for the implementation of efficient compilers. However, the existence hierarchical naming syntax as demonstrated in sample2 can have implications that affect any declaration order rules. When reaching into a module with a hierarchical name, the module being referenced is already completely declared (or not declared at all, as in sample2) so module_item order is completely irrelevant. But a "declare before use" rule would infect module ordering, by requiring that modules that are used be first defined. * TASK AND FUNCTION PARAMETERS CANNOT HAVE EXPLICIT TYPES Consider a function negate that wants to take a signed integer value and return its negative:: function integer negate; input [15:0] val; negate = -val; endfunction This is not quite right, because the input is implicitly a reg type, which is unsigned. The result, then, will always be a negative value, even if a negative val is passed in. It is possible to fix up this specific example to work properly with the bit pattern of a 16bit number, but that is not the point. What's needed is clarification on whether an input can be declared in the port declaration as well as in the contained block declaration. As I understand the situation, this should be allowed:: function integer negate; input [15:0] val; reg signed [15:0] val; negate = -val; endfunction In the -1995 standard, the variable is already implicitly a reg if declared within a function or task. However, in the -2000 standard there is now (as in this example) a reason why one might want to actually declare the type explicitly. I think that a port *cannot* be declared as an integer or time type (though the result can) because the range of the port declaration must match the range of the integer/time declaration, but the range of integers is unspecified. This, by the way, also applies to module ports. With the above in mind, I have decided to *allow* function and task ports to be declared with types, as long as the types are variable types, such as reg or integer. Without this, there would be no portable way to pass integers into functions/tasks. The standard does not say it is allowed, but it doesn't *disallow* it, and other commercial tools seem to work similarly. * ROUNDING OF TIME When the \`timescale directive is present, the compiler is supposed to round fractional times (after scaling) to the nearest integer. The confusing bit here is that it is apparently conventional that if the \`timescale directive is *not* present, times are rounded towards zero always. * VALUE OF X IN PRIMITIVE OUTPUTS The IEEE1364-1995 standard clearly states in Table 8-1 that the x symbols is allowed in input columns, but is not allowed in outputs. Furthermore, none of the examples have an x in the output of a primitive. Table 8-1 in the IEEE1364-2000 also says the same thing. However, the BNF clearly states that 0, 1, x and X are valid output_symbol characters. The standard is self contradictory. So I take it that x is allowed, as that is what Verilog-XL does. * REPEAT LOOPS vs. REPEAT EVENT CONTROL There seems to be ambiguity in how code like this should be parsed:: repeat (5) @(posedge clk) ; There are two valid interpretations of this code, from the IEEE1364-1995 standard. One looks like this:: procedural_timing_control_statement ::= delay_or_event_control statement_or_null delay_or_event_control ::= event_control | repeat ( expression ) event_control If this interpretation is used, then the statement should be executed after the 5th posedge of clk. However, there is also this interpretation:: loop_statement ::= repeat ( expression ) statement If *this* interpretation is used, then should be executed 5 times on the posedge of clk. The way the -1995 standard is written, these are both equally valid interpretations of the example, yet they produce very different results. The standard offers no guidance on how to resolve this conflict, and the IEEE1364-2000 DRAFT does not improve the situation. Practice suggests that a repeat followed by an event control should be interpreted as a loop head, and this is what Icarus Verilog does, as well as all the other major Verilog tools, but the standard does not say this. * UNSIZED NUMERIC CONSTANTS ARE NOT LIMITED TO 32 BITS The Verilog standard allows Verilog implementations to limit the size of unsized constants to a bit width of at least 32. That means that a constant 17179869183 (36'h3_ffff_ffff) may overflow some compilers. In fact, it is common to limit these values to 32bits. However, a compiler may just as easily choose another width limit, for example 64bits. That value is equally good. However, it is not *required* that an implementation truncate at 32 bits, and in fact Icarus Verilog does not truncate at all. It will make the unsized constant as big as it needs to be to hold the value accurately. This is especially useful in situations like this:: reg [width-1:0] foo = 17179869183; The programmer wants the constant to take on the width of the reg, which in this example is parameterized. Since constant sizes cannot be parameterized, the programmer ideally gives an unsized constant, which the compiler then expands/contracts to match the l-value. Also, by choosing to not ever truncate, Icarus Verilog can handle code written for a 64bit compiler as easily as for a 32bit compiler. In particular, any constants that the user does not expect to be arbitrarily truncated by his compiler will also not be truncated by Icarus Verilog, no matter what that other compiler chooses as a truncation point. * UNSIZED EXPRESSIONS AS PARAMETERS TO CONCATENATION {} The Verilog standard clearly states in 4.1.14:: "Unsized constant numbers shall not be allowed in concatenations. This is because the size of each operand in the concatenation is needed to calculate the complete size of the concatenation." So for example the expression {1'b0, 16} is clearly illegal. It also stands to reason that {1'b0, 15+1} is illegal, for exactly the same justification. What is the size of the expression (15+1)? Furthermore, it is reasonable to expect that (16) and (15+1) are exactly the same so far as the compiler is concerned. Unfortunately, Cadence seems to feel otherwise. In particular, it has been reported that although {1'b0, 16} causes an error, {1'b0, 15+1} is accepted. Further testing shows that any expression other than a simple unsized constant is accepted there, even if all the operands of all the operators that make up the expression are unsized integers. This is a semantic problem. Icarus Verilog doesn't limit the size of integer constants. This is valid as stated in 2.5.1 Note 3:: "The number of bits that make up an unsized number (which is a simple decimal number or a number without the size specification) shall be *at*least* 32." [emphasis added] Icarus Verilog will hold any integer constant, so the size will be as large as it needs to be, whether that is 64bits, 128bits, or more. With this in mind, what is the value of these expressions? :: {'h1_00_00_00_00} {'h1 << 32} {'h0_00_00_00_01 << 32} {'h5_00_00_00_00 + 1} These examples show that the standard is justified in requiring that the operands of concatenation have size. The dispute is what it takes to cause an expression to have a size, and what that size is. Verilog-XL claims that (16) does not have a size, but (15+1) does. The size of the expression (15+1) is the size of the adder that is created, but how wide is the adder when adding unsized constants? One might note that the quote from section 4.1.14 says "Unsized *constant*numbers* shall not be allowed." It does not say "Unsized expressions...", so arguably accepting (15+1) or even (16+0) as an operand to a concatenation is not a violation of the letter of the law. However, the very next sentence of the quote expresses the intent, and accepting (15+1) as having a more defined size than (16) seems to be a violation of that intent. Whatever a compiler decides the size is, the user has no way to predict it, and the compiler should not have the right to treat (15+1) any differently than (16). Therefore, Icarus Verilog takes the position that such expressions are *unsized* and are not allowed as operands to concatenations. Icarus Verilog will in general assume that operations on unsized numbers produce unsized results. There are exceptions when the operator itself does define a size, such as the comparison operators or the reduction operators. Icarus Verilog will generate appropriate error messages. * MODULE INSTANCE WITH WRONG SIZE PORT LIST A module declaration like this declares a module that takes three ports:: module three (a, b, c); input a, b, c; reg x; endmodule This is fine and obvious. It is also clear from the standard that these are legal instantiations of this module:: three u1 (x,y,z); three u2 ( ,y, ); three u3 ( , , ); three u4 (.b(y)); In some of the above examples, there are unconnected ports. In the case of u4, the pass by name connects only port b, and leaves a and c unconnected. u2 and u4 are the same thing, in fact, but using positional or by-name syntax. The next example is a little less obvious:: three u4 (); The trick here is that strictly speaking, the parser cannot tell whether this is a list of no pass by name ports (that is, all unconnected) or an empty positional list. If this were an empty positional list, then the wrong number of ports is given, but if it is an empty by-name list, it is an obviously valid instantiation. So it is fine to accept this case as valid. These are more doubtful:: three u5(x,y); three u6(,); These are definitely positional port lists, and they are definitely the wrong length. In this case, the standard is not explicit about what to do about positional port lists in module instantiations, except that the first is connected to the first, second to second, etc. It does not say that the list must be the right length, but every example of unconnected ports used by-name syntax, and every example of ordered list has the right size list. Icarus Verilog takes the (very weak) hint that ordered lists should be the right length, and will therefore flag instances u5 and u6 as errors. The IEEE1364 standard should be more specific one way or the other. * UNKNOWN VALUES IN L-VALUE BIT SELECTS Consider this example:: reg [7:0] vec; wire [4:0] idx = ; [...] vec[idx] = 1; So long as the value of idx is a valid bit select address, the behavior of this assignment is obvious. However, there is no explicit word in the standard as to what happens if the value is out of range. The standard clearly states the value of an expression when the bit-select or part select is out of range (the value is x) but does not address the behavior when the expression is an l-value. Icarus Verilog will take the position that bit select expressions in the l-value will select oblivion if it is out of range. That is, if idx has a value that is not a valid bit select of vec, then the assignment will have no effect. * SCHEDULING VALUES IN LOGIC The interaction between blocking assignments in procedural code and logic gates in gate-level code and expressions is poorly defined in Verilog. Consider this example:: reg a; reg b; wire q = a & b; initial begin a = 1; b = 0; #1 b = 1; if (q !== 0) begin $display("FAILED -- q changed too soon? %b", q); $finish; end end This is a confusing situation. It is clear from the Verilog standard that an assignment to a variable using a blocking assign causes the l-value to receive the value before the assignment completes. This means that a subsequent read of the assigned variable *must* read back what was blocking-assigned. However, in the example above, the "wire q = a & b" expresses some gate logic between a/b and q. The standard does not say whether a read out of logic should read the value computed from previous assigns to the input from the same thread. Specifically, when "a" and "b" are assigned by blocking assignments, will a read of "q" get the computed value or the existing value? In fact, existing commercial tools do it both ways. Some tools print the FAILED message in the above example, and some do not. Icarus Verilog does not print the FAILED message in the above example, because the gate value change is *scheduled* when inputs are assigned, but not propagated until the thread gives up the processor. Icarus Verilog chooses this behavior in order to filter out zero-width pulses as early as possible. The implication of this is that a read of the output of combinational logic will most likely *not* reflect the changes in inputs until the thread that changed the inputs yields execution. * BIT AND PART SELECTS OF PARAMETERS Bit and part selects are supposed to only be supported on vector nets and variables (wires, regs, etc.) However, it is common for Verilog compilers to also support bit and part select on parameters. Icarus Verilog also chooses to support bit and part selects on parameter names, but we need to define what that means. A bit or a part select on a parameter expression returns an unsigned value with a defined size. The parameter value is considered be a constant vector of bits foo[X:0]. That is, zero based. The bit and part selects operate from that assumption. Verilog 2001 adds syntax to allow the user to explicitly declare the parameter range (i.e. parameter [5:0] foo = 9;) so Icarus Verilog will (or should) use the explicitly declared vector dimensions to interpret bit and part selects. * EDGES OF VECTORS Consider this example:: reg [ 5:0] clock; always @(posedge clock) [do stuff] The IEEE1364 standard clearly states that the @(posedge clock) looks only at the bit clock[0] (the least significant bit) to search for edges. It has been pointed out by some that Verilog XL instead implements it as `@(posedge |clock)`: it looks for a rise in the reduction or of the vector. Cadence Design Systems technical support has been rumored to claim that the IEEE1364 specification is wrong, but NC-Verilog behaves according to the specification, and thus different from XL. Icarus Verilog, therefore, takes the position that the specification is clear and correct, and it behaves as does NC-Verilog in this matter. * REAL VARIABLES IN $dumpoff DEAD-ZONES The IEEE1364 standard clearly states that in VCD files, the $dumpoff section checkpoints all the dumped variables as X values. For reg and wire bits/vectors, this obviously means 'bx values. Icarus Verilog does this, for example:: $dumpoff x! x" $end Real variables can also be included in VCD dumps, but it is not at all obvious what is supposed to be dumped into the $dumpoff-$end section of the VCD file. Verilog-XL dumps "r0 !" to set the real variables to the dead-zone value of 0.0, whereas other tools, such as ModelTech, ignore real variables in this section. For example (from XL):: $dumpoff r0 ! r0 " $end Icarus Verilog dumps NaN values for real variables in the $dumpoff-$end section of the VCD file. The NaN value is the IEEE754 equivalent of an unknown value, and so better reflects the unknown (during the dead zone) status of the variable, like this:: $dumpoff rNaN ! rNaN " $end It turns out that NaN is conventionally accepted by scanf functions, and viewers that support real variables support NaN values. So while the IEEE1364 doesn't require this behavior, and given the variety that already seems to exist amongst VCD viewers in the wild, this behavior seems to be acceptable according to the standard, is a better mirror of 4-value behavior in the dead zone, and appears more user friendly when viewed by reasonable viewers. iverilog-13_0/Documentation/developer/guide/misc/index.rst000066400000000000000000000001461515114676500240410ustar00rootroot00000000000000 Miscellaneous ============= .. toctree:: :maxdepth: 1 ieee1364-notes swift xilinx-hint iverilog-13_0/Documentation/developer/guide/misc/swift.rst000066400000000000000000000045601515114676500240720ustar00rootroot00000000000000 Swift Model Support (Preliminary) ================================= Copyright 2003-2024 Stephen Williams NOTE: SWIFT support does not work yet, these are provisional instructions, intended to show what's supposed to happen when I get it working. Icarus Verilog support for SWIFT models is based on the LMTV interface module from Synopsys. This module is normally distributed along with the SWIFT models proper. This module can be linked with Icarus Verilog via the cadpli compatibility object. (See cadpli.txt.) * Preliminaries First, you need the LMC_HOME environment variable set to point to the installed directory for your SWIFT software. This setup is documented in your SWIFT model documentation. * Compilation When compiling your Verilog design to include a SWIFT model, you need to include wrappers for the model you intend to use. You may choose to use ncverilog or verilogxl compatible wrappers, they work the same. Locate your smartmodel directory, and include it in your command file like so:: +libdir+.../smartmodel/sol/wrappers/verilogxl The wrappers directory includes Verilog modules that wrap your SWIFT module, and with this +libdir+ statement in your command file, the Icarus Verilog compiler will be able to locate these wrappers. The wrappers in turn invoke the $lm_model system tasks that are the LMTV support for your model. NOTE: This example uses the solaris directory of VerilogXL support files as a source of wrappers. The files of interest, however, are written in Verilog and are identical for all supported platforms, so long as you choose the verilogxl or ncverilog files. * Execution After your simulation is compiled, run the simulation with the vvp command, like this:: % vvp -mcadpli a.out -cadpli=$LMC_HOME/lib/x86_linux.lib/swiftpli.so:swift_boot What this command line means is:: -mcadpli Include the cadpli compatibility module a.out This is your compiled vvp file -cadpli=$LMC_HOME/lib/x86_linux.lib/swiftpli.so:swift_boot This tells the cadpli module to load the swiftpli.so shared object, and boot it. This is code that comes with your SWIFT modules, and provides the generic SWIFT capabilities (lm_* system tasks) needed by the module itself. Once you start the vvp command, the SWIFT infrastructure will be initialized as part of the simulation setup, and all should work normally from here. iverilog-13_0/Documentation/developer/guide/misc/xilinx-hint.rst000066400000000000000000000072611515114676500252120ustar00rootroot00000000000000 Xilinx Hint =========== For those of you who wish to use Icarus Verilog, in combination with the Xilinx back end (Foundation or Alliance), it can be done. I have run some admittedly simple (2300 equivalent gates) designs through this setup, targeting a Spartan XCS10. Verilog: -------- Older versions of Icarus Verilog (like 19990814) couldn't synthesize logic buried in procedural (flip-flop) assignment. Newer versions (like 20000120) don't have this limitation. Procedural assignments have to be given one at a time, to be "found" by xnfsyn. Say :: always @ (posedge Clk) Y = newY; always @ (posedge Clk) Z = newZ; rather than :: always @ (posedge Clk) begin Y = newY; Z = newZ; end Steve's xnf.txt covers most buffer and pin constructs, but I had reason to use a global clock net not connected to an input pin. The standard Verilog for a buffer, combined with a declaration to turn that into a BUFG, is:: buf BUFG( your_output_here, your_input_here ); $attribute(BUFG,"XNF-LCA","BUFG:O,I") I use post-processing on my .xnf files to add "FAST" attributes to output pins. Running ivl: ------------ The -F switches are important. The following order seems to robustly generate valid XNF files, and is used by "verilog -X":: -Fsynth -Fnodangle -Fxnfio Generating .pcf files: ---------------------- The ngdbuild step seems to lose pin placement information that ivl puts in the XNF file. Use xnf2pcf to extract this information to a .pcf file, which the Xilinx place-and-route software _will_ pay attention to. Steve says he now makes that information available in an NCF file, with -fncf=, but I haven't tested that. Running the Xilinx back end: You can presumably use the GUI, but that doesn't fit in Makefiles :-). Here is the command sequence in pseudo-shell-script:: ngdbuild -p $part $1.xnf $1.ngd map -p $part -o map.ncd $1.ngd xnf2pcf <$1.xnf >$1.pcf # see above par -w -ol 2 -d 0 map.ncd $1.ncd $1.pcf bitgen_flags = -g ConfigRate:SLOW -g TdoPin:PULLNONE -g DonePin:PULLUP \ -g CRC:enable -g StartUpClk:CCLK -g SyncToDone:no \ -g DoneActive:C1 -g OutputsActive:C3 -g GSRInactive:C4 \ -g ReadClk:CCLK -g ReadCapture:enable -g ReadAbort:disable bitgen $1.ncd -l -w $bitgen_flags The Xilinx software has diarrhea of the temp files (14, not including .xnf, .pcf, .ngd, .ncd, and .bit), so this sequence is best done in a dedicated directory. Note in particular that map.ncd is a generic name. I had reason to run this remotely (and transparently within a Makefile) via ssh. I use the gmake rule:: %.bit : %.xnf ssh -x -a -o 'BatchMode yes' ${ALLIANCE_HOST} \ remote_alliance ${REMOTE_DIR} $(basename $@) 2>&1 < $< scp ${ALLIANCE_HOST}:${REMOTE_DIR}/$@ . and the remote_alliance script (on ${ALLIANCE_HOST}):: /bin/csh cd $1 cat >! $2.xnf xnf2pcf <$2.xnf >! $2.pcf ./backend $2 There is now a "Xilinx on Linux HOWTO" at http://www.polybus.com/xilinx_on_linux.html I haven't tried this yet, it looks interesting. Downloading: ------------ I use the XESS (http://www.xess.com/) XSP-10 development board, which uses the PC parallel (printer) port for downloading and interaction with the host. They made an old version of their download program public domain, posted it at http://www.xess.com/FPGA/xstools.zip , and now there is a Linux port at ftp://ftp.microux.com/pub/pilotscope/xstools.tar.gz . The above hints are based on my experience with Foundation 1.5 on NT (gack) and Alliance 2.1i on Solaris. Your mileage may vary. Good luck! - Larry Doolittle August 19, 1999 updated February 1, 2000 iverilog-13_0/Documentation/developer/guide/tgt-vvp/000077500000000000000000000000001515114676500226535ustar00rootroot00000000000000iverilog-13_0/Documentation/developer/guide/tgt-vvp/tgt-vvp.rst000066400000000000000000000020261515114676500250140ustar00rootroot00000000000000 The VVP Target ============== Symbol Name Conventions ----------------------- There are some naming conventions that the vvp target uses for generating symbol names. * wires and regs Nets and variables are named V_ where is the full hierarchical name of the signal. * Logic devices Logic devices (and, or, buf, bufz, etc.) are named L_. In this case the symbol is attached to a functor that is the output of the logic device. General Functor Web Structure ----------------------------- The net of gates, signals and resolvers is formed from the input design. The basic structure is wrapped around the nexus, which is represented by the ivl_nexus_t. Each nexus represents a resolved value. The input of the nexus is fed by a single driver. If the nexus in the design has multiple drivers, the drivers are first fed into a resolver (or a tree of resolvers) to form a single output that is the nexus. The nexus, then, feeds its output to the inputs of other gates, or to the .net objects in the design. iverilog-13_0/Documentation/developer/guide/vpi/000077500000000000000000000000001515114676500220425ustar00rootroot00000000000000iverilog-13_0/Documentation/developer/guide/vpi/index.rst000066400000000000000000000001361515114676500237030ustar00rootroot00000000000000 VPI in Icarus Verilog ===================== .. toctree:: :maxdepth: 1 vpi va_math iverilog-13_0/Documentation/developer/guide/vpi/va_math.rst000066400000000000000000000066131515114676500242210ustar00rootroot00000000000000 Verilog-A math library ====================== License. -------- Verilog-A math library built for Icarus Verilog https://github.com/steveicarus/iverilog/ Copyright (C) 2007-2024 Cary R. (cygcary@yahoo.com) 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. Standard Verilog-A Mathematical Functions. ------------------------------------------ The va_math VPI module implements all the standard math functions provided by Verilog-A as Verilog-D system functions. The names are the same except like all Verilog-D system functions the name must be prefixed with a '$'. For reference the functions are:: $ln(x) -- Natural logarithm $log10(x) -- Decimal logarithm $exp(x) -- Exponential $sqrt(x) -- Square root $min(x,y) -- Minimum $max(x,y) -- Maximum $abs(x) -- Absolute value $floor(x) -- Floor $ceil(x) -- Ceiling $pow(x,y) -- Power (x**y) $sin(x) -- Sine $cos(x) -- Cosine $tan(x) -- Tangent $asin(x) -- Arc-sine $acos(x) -- Arc-cosine $atan(x) -- Arc-tangent $atan2(y,x) -- Arc-tangent of y/x $hypot(x,y) -- Hypotenuse (sqrt(x**2 + y**2)) $sinh(x) -- Hyperbolic sine $cosh(x) -- Hyperbolic cosine $tanh(x) -- Hyperbolic tangent $asinh(x) -- Arc-hyperbolic sine $acosh(x) -- Arc-hyperbolic cosine $atanh(x) -- Arc-hyperbolic tangent The only limit placed on the x and y arguments by the library is that they must be numbers (not constant strings). The underlying C library controls any other limits placed on the arguments. Most libraries return +-Inf or NaN for results that cannot be represented with real numbers. All functions return a real result. Standard Verilog-A Mathematical Constants. ------------------------------------------ The Verilog-A mathematical constants can be accessed by including the "constants.vams" header file. It is located in the standard include directory. Recent version of Icarus Verilog (0.9.devel) automatically add this directory to the end of the list used to find include files. For reference the mathematical constants are:: `M_PI -- Pi `M_TWO_PI -- 2*Pi `M_PI_2 -- Pi/2 `M_PI_4 -- Pi/4 `M_1_PI -- 1/Pi `M_2_PI -- 2/Pi `M_2_SQRTPI -- 2/sqrt(Pi) `M_E -- e `M_LOG2E -- log base 2 of e `M_LOG10E -- log base 10 of e `M_LN2 -- log base e of 2 `M_LN10 -- log base e of 10 `M_SQRT2 -- sqrt(2) `M_SQRT1_2 -- 1/sqrt(2) Using the Library. ------------------ Just add "-m va_math" to your iverilog command line/command file and \`include the "constants.vams" file as needed. Thanks ------ I would like to thank Larry Doolittle for his suggestions and Stephen Williams for developing Icarus Verilog. iverilog-13_0/Documentation/developer/guide/vpi/vpi.rst000066400000000000000000000042451515114676500233770ustar00rootroot00000000000000 VPI Modules in Icarus Verilog ================================ The VPI interface for Icarus Verilog works by creating from a collection of PLI applications a single vpi module. The vpi module includes compiled code for the applications linked together (with any other libraries that the applications need) into a module with two exported symbols, the vpip_set_callback function and the vlog_startup_routines array. The product that wishes to invoke the module (normally at run time) loads the module, locates and calls the vpip_set_callback function to pass the the module a jump table that allows the module to access the VPI routines implemented by the product, then locates the vlog_startup_routines table and calls all the startup routines contained in that table. It is possible for a product to link with many modules. In that case, all the modules are linked in and startup routines are called in order. The product that uses vpi modules uses the environment variable VPI_MODULE_PATH as a ':' separated list of directories. This is the module search path. When a module is specified by name (using whatever means the product supports) the module search path is scanned until the module is located. The special module names "system.vpi", "v2005_math.vpi", "v2009.vpi", and "va_math.vpi" are part of the core Icarus Verilog distribution and include implementations of the standard system tasks/functions. The additional special module names "vhdl_sys.vpi" and "vhdl_textio.vpi" include implementations of private functions used to support VHDL. Compiling A VPI Module ---------------------- See the documentation under: :doc:`Using VPI <../../../usage/vpi>` Tracing VPI Use --------------- The vvp command includes the ability to trace VPI calls. This is useful if you are trying to debug a problem with your code. To activate tracing simply set the VPI_TRACE environment variable, with the path to a file where trace text gets written. For example:: setenv VPI_TRACE /tmp/foo.txt This tracing is pretty verbose, so you don't want to run like this normally. Also, the format of the tracing messages will change according to my needs (and whim) so don't expect to be able to parse it in software. iverilog-13_0/Documentation/developer/guide/vvp/000077500000000000000000000000001515114676500220575ustar00rootroot00000000000000iverilog-13_0/Documentation/developer/guide/vvp/debug.rst000066400000000000000000000011421515114676500236750ustar00rootroot00000000000000 Debug Aids For VVP ================== Debugging vvp can be fiendishly difficult, so there are some built in debugging aids. These are enabled by setting the environment variable VVP_DEBUG to the path to an output file. Then, various detailed debug tools can be enabled as described below. * .resolv The .resolv can print debug information along with a label by specifying the debug output label on the .resolv line:: .resolv tri$